Valentin David pushed to branch valentindavid/link_files_sort_resolved at BuildStream / buildstream
Commits:
-
65725d00
by Valentin David at 2018-11-13T23:06:13Z
6 changed files:
- buildstream/utils.py
- tests/integration/compose-symlinks.py
- + tests/integration/project/elements/compose-symlinks/a-foo-symlink.bst
- + tests/integration/project/elements/compose-symlinks/compose-absolute-symlink.bst
- + tests/integration/project/elements/compose-symlinks/foo-dir.bst
- + tests/integration/project/elements/compose-symlinks/integration-move-dir.bst
Changes:
| ... | ... | @@ -743,6 +743,48 @@ def _ensure_real_directory(root, destpath): |
| 743 | 743 |
return destpath_resolved
|
| 744 | 744 |
|
| 745 | 745 |
|
| 746 |
+@functools.lru_cache(maxsize=1)
|
|
| 747 |
+def _symloop_max():
|
|
| 748 |
+ if hasattr(os, 'sysconf'):
|
|
| 749 |
+ try:
|
|
| 750 |
+ ret = os.sysconf('_SC_SYMLOOP_MAX')
|
|
| 751 |
+ if ret != -1:
|
|
| 752 |
+ return ret
|
|
| 753 |
+ except ValueError:
|
|
| 754 |
+ pass
|
|
| 755 |
+ return 8
|
|
| 756 |
+ |
|
| 757 |
+ |
|
| 758 |
+@functools.lru_cache(maxsize=64)
|
|
| 759 |
+def _sysroot_realpath(path, sysroot):
|
|
| 760 |
+ assert not os.path.isabs(path)
|
|
| 761 |
+ assert os.path.isabs(sysroot)
|
|
| 762 |
+ |
|
| 763 |
+ loop_count = _symloop_max()
|
|
| 764 |
+ while True:
|
|
| 765 |
+ full_path = os.path.join(sysroot, path)
|
|
| 766 |
+ st = os.lstat(full_path)
|
|
| 767 |
+ mode = st.st_mode
|
|
| 768 |
+ if not stat.S_ISLNK(mode):
|
|
| 769 |
+ break
|
|
| 770 |
+ loop_count = loop_count - 1
|
|
| 771 |
+ if loop_count < 0:
|
|
| 772 |
+ raise UtilError("Symlink loop detected: {}".format(os.path.join(sysroot, path)))
|
|
| 773 |
+ link_path = os.readlink(full_path)
|
|
| 774 |
+ if not os.path.isabs(link_path):
|
|
| 775 |
+ link_path = os.path.join('/', os.path.dirname(path), link_path)
|
|
| 776 |
+ path = os.path.relpath(os.path.normpath(link_path), '/')
|
|
| 777 |
+ |
|
| 778 |
+ parent = os.path.dirname(path)
|
|
| 779 |
+ if parent != '':
|
|
| 780 |
+ parent = _sysroot_realpath(parent, sysroot)
|
|
| 781 |
+ full_parent = os.path.join(sysroot, parent)
|
|
| 782 |
+ if not os.path.isdir(full_parent):
|
|
| 783 |
+ raise UtilError("Path is not a directory: {}".format(full_parent))
|
|
| 784 |
+ |
|
| 785 |
+ return os.path.join(parent, os.path.basename(path))
|
|
| 786 |
+ |
|
| 787 |
+ |
|
| 746 | 788 |
# _process_list()
|
| 747 | 789 |
#
|
| 748 | 790 |
# Internal helper for copying/moving/linking file lists
|
| ... | ... | @@ -773,10 +815,10 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, |
| 773 | 815 |
# those directories.
|
| 774 | 816 |
if not presorted:
|
| 775 | 817 |
resolved = []
|
| 818 |
+ _sysroot_realpath.cache_clear()
|
|
| 776 | 819 |
for f in filelist:
|
| 777 | 820 |
dirname = os.path.dirname(f)
|
| 778 |
- dirname = os.path.realpath(os.path.join(srcdir, dirname))
|
|
| 779 |
- dirname = os.path.relpath(dirname, srcdir)
|
|
| 821 |
+ dirname = _sysroot_realpath(dirname, srcdir)
|
|
| 780 | 822 |
if dirname == '.':
|
| 781 | 823 |
resolved.append(os.path.basename(f))
|
| 782 | 824 |
else:
|
| ... | ... | @@ -41,3 +41,18 @@ def test_compose_symlinks(cli, tmpdir, datafiles): |
| 41 | 41 |
|
| 42 | 42 |
assert set(walk_dir(checkout)) == set(['/sbin', '/usr', '/usr/sbin',
|
| 43 | 43 |
'/usr/sbin/init', '/usr/sbin/dummy'])
|
| 44 |
+ |
|
| 45 |
+ |
|
| 46 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 47 |
+def test_compose_absolute_symlinks(cli, tmpdir, datafiles):
|
|
| 48 |
+ project = str(datafiles)
|
|
| 49 |
+ checkout = os.path.join(cli.directory, 'checkout')
|
|
| 50 |
+ element_path = os.path.join(project, 'elements')
|
|
| 51 |
+ |
|
| 52 |
+ result = cli.run(project=project, args=['build', 'compose-symlinks/compose-absolute-symlink.bst'])
|
|
| 53 |
+ result.assert_success()
|
|
| 54 |
+ |
|
| 55 |
+ result = cli.run(project=project, args=['checkout', 'compose-symlinks/compose-absolute-symlink.bst', checkout])
|
|
| 56 |
+ result.assert_success()
|
|
| 57 |
+ |
|
| 58 |
+ assert os.readlink(os.path.join(checkout, 'foo')) == 'test/foo'
|
| 1 |
+kind: script
|
|
| 2 |
+ |
|
| 3 |
+depends:
|
|
| 4 |
+- filename: base.bst
|
|
| 5 |
+ type: build
|
|
| 6 |
+ |
|
| 7 |
+config:
|
|
| 8 |
+ commands:
|
|
| 9 |
+ - |
|
|
| 10 |
+ mkdir -p "%{install-root}/bar"
|
|
| 11 |
+ ln -s "/bar" "%{install-root}/foo"
|
| 1 |
+kind: compose
|
|
| 2 |
+ |
|
| 3 |
+depends:
|
|
| 4 |
+- filename: compose-symlinks/foo-dir.bst
|
|
| 5 |
+ type: build
|
|
| 6 |
+- filename: compose-symlinks/a-foo-symlink.bst
|
|
| 7 |
+ type: build
|
|
| 8 |
+- filename: compose-symlinks/integration-move-dir.bst
|
|
| 9 |
+ type: build
|
|
| 10 |
+ |
|
| 11 |
+config:
|
|
| 12 |
+ include-orphans: true
|
|
| 13 |
+ exclude:
|
|
| 14 |
+ - dummy
|
| 1 |
+kind: script
|
|
| 2 |
+ |
|
| 3 |
+depends:
|
|
| 4 |
+- filename: base.bst
|
|
| 5 |
+ type: build
|
|
| 6 |
+ |
|
| 7 |
+config:
|
|
| 8 |
+ commands:
|
|
| 9 |
+ - |
|
|
| 10 |
+ mkdir -p "%{install-root}/foo"
|
|
| 11 |
+ echo test >"%{install-root}/foo/foo.txt"
|
| 1 |
+kind: stack
|
|
| 2 |
+ |
|
| 3 |
+depends:
|
|
| 4 |
+- filename: base.bst
|
|
| 5 |
+ |
|
| 6 |
+public:
|
|
| 7 |
+ bst:
|
|
| 8 |
+ integration-commands:
|
|
| 9 |
+ - |
|
|
| 10 |
+ mkdir test
|
|
| 11 |
+ mv foo test/
|
|
| 12 |
+ ln -s /test/foo /foo
|
