diff options
author | Jürg Billeter <j@bitron.ch> | 2019-01-28 19:21:31 +0000 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2019-02-14 16:05:38 +0100 |
commit | 55bccf630f1ffec9a4d5c1a601e7580a8c2ced3f (patch) | |
tree | 65ec73ba05c518b4e5850347223c74e2eb1dd1bd | |
parent | c05708718b06d8fdc0151d7bb474e9beb2eb336b (diff) | |
download | buildstream-55bccf630f1ffec9a4d5c1a601e7580a8c2ced3f.tar.gz |
utils.py: Do not mangle absolute symlinks
Copy symlinks as they are, absolute or relative. We no longer resolve
symlinks when copying files, which makes this safe.
-rw-r--r-- | buildstream/utils.py | 52 | ||||
-rw-r--r-- | tests/integration/symlinks.py | 11 |
2 files changed, 4 insertions, 59 deletions
diff --git a/buildstream/utils.py b/buildstream/utils.py index adc593d7c..a4e84097b 100644 --- a/buildstream/utils.py +++ b/buildstream/utils.py @@ -34,7 +34,6 @@ import string import subprocess import tempfile import itertools -import functools from contextlib import contextmanager import psutil @@ -767,11 +766,6 @@ def _copy_directories(srcdir, destdir, target): 'directory expected: {}'.format(old_dir)) -@functools.lru_cache(maxsize=64) -def _resolve_symlinks(path): - return os.path.realpath(path) - - # _ensure_real_directory() # # Ensure `path` is a real directory and there are no symlink components. @@ -872,7 +866,6 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, continue target = os.readlink(srcpath) - target = _relative_symlink_target(destdir, destpath, target) os.symlink(target, destpath) elif stat.S_ISREG(mode): @@ -910,51 +903,6 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, os.chmod(d, perms) -# _relative_symlink_target() -# -# Fetches a relative path for symlink with an absolute target -# -# @root: The staging area root location -# @symlink: Location of the symlink in staging area (including the root path) -# @target: The symbolic link target, which may be an absolute path -# -# If @target is an absolute path, a relative path from the symbolic link -# location will be returned, otherwise if @target is a relative path, it will -# be returned unchanged. -# -# Using relative symlinks helps to keep the target self contained when staging -# files onto the target. -# -def _relative_symlink_target(root, symlink, target): - - if os.path.isabs(target): - # First fix the input a little, the symlink itself must not have a - # trailing slash, otherwise we fail to remove the symlink filename - # from its directory components in os.path.split() - # - # The absolute target filename must have its leading separator - # removed, otherwise os.path.join() will discard the prefix - symlink = symlink.rstrip(os.path.sep) - target = target.lstrip(os.path.sep) - - # We want a relative path from the directory in which symlink - # is located, not from the symlink itself. - symlinkdir, _ = os.path.split(_resolve_symlinks(symlink)) - - # Create a full path to the target, including the leading staging - # directory - fulltarget = os.path.join(_resolve_symlinks(root), target) - - # now get the relative path from the directory where the symlink - # is located within the staging root, to the target within the same - # staging root - newtarget = os.path.relpath(fulltarget, symlinkdir) - - return newtarget - else: - return target - - # _set_deterministic_user() # # Set the uid/gid for every file in a directory tree to the process' diff --git a/tests/integration/symlinks.py b/tests/integration/symlinks.py index 5674b5778..5db09d3d0 100644 --- a/tests/integration/symlinks.py +++ b/tests/integration/symlinks.py @@ -20,7 +20,7 @@ DATA_DIR = os.path.join( @pytest.mark.datafiles(DATA_DIR) @pytest.mark.skipif(not HAVE_SANDBOX, reason='Only available with a functioning sandbox') -def test_absolute_symlinks_made_relative(cli, tmpdir, datafiles): +def test_absolute_symlinks(cli, tmpdir, datafiles): project = os.path.join(datafiles.dirname, datafiles.basename) checkout = os.path.join(cli.directory, 'checkout') element_name = 'symlinks/dangling-symlink.bst' @@ -34,12 +34,9 @@ def test_absolute_symlinks_made_relative(cli, tmpdir, datafiles): symlink = os.path.join(checkout, 'opt', 'orgname') assert os.path.islink(symlink) - # The symlink is created to point to /usr/orgs/orgname, but BuildStream - # should make all symlink target relative when assembling the artifact. - # This is done so that nothing points outside the sandbox and so that - # staging artifacts in locations other than / doesn't cause the links to - # all break. - assert os.readlink(symlink) == '../usr/orgs/orgname' + # The symlink is created to point to /usr/orgs/orgname and BuildStream + # should not mangle symlinks. + assert os.readlink(symlink) == '/usr/orgs/orgname' @pytest.mark.datafiles(DATA_DIR) |