Merge lp:~mvo/click/generate-framework-initial.libs into lp:click/devel

Proposed by Michael Vogt
Status: Rejected
Rejected by: Michael Vogt
Proposed branch: lp:~mvo/click/generate-framework-initial.libs
Merge into: lp:click/devel
Diff against target: 108 lines (+54/-4)
2 files modified
click/chroot.py (+17/-3)
click/tests/test_chroot.py (+37/-1)
To merge this branch: bzr merge lp:~mvo/click/generate-framework-initial.libs
Reviewer Review Type Date Requested Status
Colin Watson Needs Fixing
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+225810@code.launchpad.net

Commit message

Generate list of shared libraries available in a fresh click chroot

Description of the change

This branch generates a list of initial libraries in a click chroot.

This is done in order to support the following two use-cases:
(1) detect if a click package links against libraries that are not part of the framework (and needs bundling)
(2) automatically bundle libraries when "click build --with-bundle-libraries" (or somesuch) is used

For (1) I have a branch lp:~mvo/click-reviewers-tools/check-libs that "just" needs to get the data what libs are available for what framework/arch combination.

If this approach to generate the data looks sensible I will update the click-reviewers-tools branch to use the data from this branch. Otherwise I would love to discuss other options.

Thanks for your consideration,
 Michael

p.s. Note that this is currently not looking at the individual symbols, just at the binaries DT_NEEDED values. If we want to look at the individual symbols then a more sophisticated approach will be needed.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:487
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~mvo/click/generate-framework-initial.libs/+merge/225810/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/click-devel-ci/26/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/click-devel-utopic-amd64-ci/28/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/click-devel-utopic-armhf-ci/26/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/click-devel-utopic-i386-ci/26/console

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/click-devel-ci/26/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Colin Watson (cjwatson) wrote :

I think if we're going to do this we need some way to ensure that the list is kept up to date when people upgrade the chroot.

review: Needs Fixing
Revision history for this message
Colin Watson (cjwatson) wrote :

We should probably only take the top-level dependencies, too. That implies that perhaps we can just figure this out from the framework package's dependencies at run-time?

Revision history for this message
Michael Vogt (mvo) wrote :

Thanks for the feedback! If we only take the so files of the toplevel dependencies of ubuntu-sdk-libs into account, then the list of supported "*.so.*" files is rather small:
"""
libQt5Script.so.5
libQt5Script.so.5.3
libQt5Script.so.5.3.1
libcontent-hub.so.0
libcontent-hub.so.0.0.1
libqt5keychain.so.0
libqt5keychain.so.0.3.0
"""

With one additional dependency level I get a list of 195 libs but I'm not sure that is really what we want (i.e. why two levels and not all levels). If we only want to follow the first dependency level, then it seems like the sdk-libs ubuntu-touch seed needs more entries. It will also mean that for something that uses e.g. Qt5GUI.so we need to ship ~30 additional libs including libX11.so.6, libstdc++.so.6, libpcre.so.3 etc if we take this narrow approach.

Revision history for this message
Colin Watson (cjwatson) wrote :

I think it's definitely worth looking at fleshing out sdk-libs, although I think germinate-update-metapackage might skip things in inner seeds; worth experimenting.

Why would we need to ship libX11.so.6 et al? We should only need to look at direct DT_NEEDED entries in object linkage, not follow the whole ldd chain. Hopefully binaries that link against Qt5GUI don't in general also overlink against all its transitive dependencies.

Revision history for this message
Michael Vogt (mvo) wrote :

Thanks Colin!

I created a (somewhat ugly) branch in lp:~mvo/click/click-check-libs that implements your suggestion to use only the first dependency level. Here is a example output:
"""
$ PYTHONPATH=. ./bin/click verify --allow-unauthenticated --check-libs com.ubuntu.camera_3.0.0.387_armhf.click
[..warnings about missing pkgs in the click chroot.. ]
libQt5Core.so.5
libQt5Gui.so.5
libQt5Multimedia.so.5
libQt5Qml.so.5
libQt5Quick.so.5
libc.so.6
libgcc_s.so.1
libstdc++.so.6
"""
which looks not bad, once libQt5* is explicitely seeded. What should happen with libc/libgcc/libstdc++, should this be added to a default whitelist?

Revision history for this message
Michael Vogt (mvo) wrote :

Some more libs I noticed when checking our clicks:
libpam.so.0
libgcc_s.so.1
libubuntuoneauth-2.0.so.0
libexpat.so.1
libm.so.6
libz.so.1
libcontent-hub.so.0

The libcontent-hub.so.0 indicates that we need to ensure to install the full ubuntu-sdk-libs:$arch into the click chroot - alternatively we could use apt-file to get this data.

Revision history for this message
Michael Vogt (mvo) wrote :

This MP is no longer needed but the comments maybe insightful so I don't delete it right away.

Unmerged revisions

487. By Michael Vogt

Generate list of initially installed libs on chroot creation

This will allow us to detect if a click package links against
libraries that are not part of the click package and not part
of a framework.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click/chroot.py'
2--- click/chroot.py 2014-07-03 11:03:24 +0000
3+++ click/chroot.py 2014-07-07 11:29:20 +0000
4@@ -318,7 +318,7 @@
5 """) % proxy)
6 return apt_conf_f
7
8- def _generate_finish_script(self, mount, build_pkgs):
9+ def _generate_finish_script(self, mount, build_pkgs, cross_libdir):
10 finish_script = "%s/finish.sh" % mount
11 with open(finish_script, 'w') as finish:
12 finish.write(dedent("""\
13@@ -342,11 +342,19 @@
14 if [ ! -r /dev/stdin ]; then ln -s /proc/self/fd/0 /dev/stdin; fi
15 if [ ! -r /dev/stdout ]; then ln -s /proc/self/fd/1 /dev/stdout; fi
16 if [ ! -r /dev/stderr ]; then ln -s /proc/self/fd/2 /dev/stderr; fi
17+ # Generate what libs we have
18+ echo "Generating default libs list"
19+ mkdir -p /var/lib/click
20+ find {cross_libdir} -name "*.so.*" | while read -r file
21+ do
22+ echo $file
23+ done | sort | uniq > /var/lib/click/initial.libs
24 # Clean up
25 rm /finish.sh
26 apt-get clean
27 """).format(target_arch=self.target_arch,
28- build_pkgs=' '.join(build_pkgs)))
29+ build_pkgs=' '.join(build_pkgs),
30+ cross_libdir=cross_libdir))
31 return finish_script
32
33 def _debootstrap(self, components, mount):
34@@ -434,7 +442,13 @@
35 os.remove("%s/sbin/initctl" % mount)
36 os.symlink("%s/bin/true" % mount, "%s/sbin/initctl" % mount)
37 self._generate_apt_proxy_file(mount, proxy)
38- finish_script = self._generate_finish_script(mount, build_pkgs)
39+ if self.native_arch == self.target_arch:
40+ cross_libdir = "/lib /lib64 /usr/lib"
41+ else:
42+ triplet = self.dpkg_architecture["DEB_HOST_GNU_TYPE"]
43+ cross_libdir = "/usr/lib/%s" % triplet
44+ finish_script = self._generate_finish_script(
45+ mount, build_pkgs, cross_libdir)
46 self._make_executable(finish_script)
47 command = ["/finish.sh"]
48 ret_code = self.maint(*command)
49
50=== modified file 'click/tests/test_chroot.py'
51--- click/tests/test_chroot.py 2014-07-02 09:07:13 +0000
52+++ click/tests/test_chroot.py 2014-07-07 11:29:20 +0000
53@@ -216,7 +216,8 @@
54 chroot = ClickChroot("i386", "ubuntu-sdk-14.04")
55 finish_script = chroot._generate_finish_script(
56 self.temp_dir,
57- ["build-pkg-1", "build-pkg-2"])
58+ ["build-pkg-1", "build-pkg-2"],
59+ "/usr/lib/arm-linux-meep")
60 with open(finish_script) as f:
61 self.assertEqual(f.read(), dedent("""\
62 #!/bin/bash
63@@ -239,6 +240,13 @@
64 if [ ! -r /dev/stdin ]; then ln -s /proc/self/fd/0 /dev/stdin; fi
65 if [ ! -r /dev/stdout ]; then ln -s /proc/self/fd/1 /dev/stdout; fi
66 if [ ! -r /dev/stderr ]; then ln -s /proc/self/fd/2 /dev/stderr; fi
67+ # Generate what libs we have
68+ echo "Generating default libs list"
69+ mkdir -p /var/lib/click
70+ find /usr/lib/arm-linux-meep -name "*.so.*" | while read -r file
71+ do
72+ echo $file
73+ done | sort | uniq > /var/lib/click/initial.libs
74 # Clean up
75 rm /finish.sh
76 apt-get clean
77@@ -338,3 +346,31 @@
78 ("ubuntu-sdk-14.04-dev99", "ubuntu-sdk-14.04"),
79 ):
80 self.assertEqual(strip_dev_series_from_framework(have), want)
81+
82+ def test_chroot_create_generates_finished_script_native(self):
83+ self.use_temp_dir()
84+ chroot = FakeClickChroot(
85+ "i386", "ubuntu-sdk-14.04",
86+ chroots_dir=self.temp_dir, temp_dir=self.temp_dir)
87+ chroot.native_arch = "i386"
88+ chroot.create()
89+ finish_script = os.path.join(
90+ self.temp_dir, "click-ubuntu-sdk-14.04-i386", "finish.sh")
91+ with open(finish_script) as f:
92+ self.assertIn(
93+ 'find /lib /lib64 /usr/lib -name "*.so.*" |', f.read())
94+
95+ def test_chroot_create_generates_finished_script_foreign(self):
96+ self.use_temp_dir()
97+ chroot = FakeClickChroot(
98+ "armhf", "ubuntu-sdk-14.04",
99+ chroots_dir=self.temp_dir, temp_dir=self.temp_dir)
100+ chroot.native_arch = "i386"
101+ chroot.create()
102+ finish_script = os.path.join(
103+ self.temp_dir, "click-ubuntu-sdk-14.04-armhf", "finish.sh")
104+ with open(finish_script) as f:
105+ haystack = f.read()
106+ self.assertIn(
107+ 'find /usr/lib/arm-linux-gnueabihf -name "*.so.*" |',
108+ haystack)

Subscribers

People subscribed via source and target branches

to all changes: