summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2019-01-28 19:21:31 +0000
committerJürg Billeter <j@bitron.ch>2019-02-14 16:05:38 +0100
commit55bccf630f1ffec9a4d5c1a601e7580a8c2ced3f (patch)
tree65ec73ba05c518b4e5850347223c74e2eb1dd1bd
parentc05708718b06d8fdc0151d7bb474e9beb2eb336b (diff)
downloadbuildstream-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.py52
-rw-r--r--tests/integration/symlinks.py11
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)