Valentin David pushed to branch valentindavid/link_files_sort_resolved at BuildStream / buildstream
Commits:
-
e42916f3
by Valentin David at 2018-11-14T10:42:28Z
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 |
+ mv bar test/
|
|
13 |
+ ln -s /test/foo /foo
|
|
14 |
+ ln -s /test/bar /bar
|