Merge lp:~aptdaemon-developers/aptdaemon/lintian-profiles into lp:aptdaemon

Proposed by Sebastian Heinlein
Status: Merged
Merged at revision: 841
Proposed branch: lp:~aptdaemon-developers/aptdaemon/lintian-profiles
Merge into: lp:aptdaemon
Diff against target: 388 lines (+124/-143)
9 files modified
NEWS (+3/-0)
aptdaemon/progress.py (+45/-0)
aptdaemon/worker.py (+10/-43)
data/lintian-fatal.tags (+0/-66)
data/lintian-nonfatal.tags (+0/-25)
data/lintian/debian/aptdaemon.profile (+7/-0)
data/lintian/ubuntu/aptdaemon.profile (+43/-0)
setup.py (+4/-2)
tests/test_worker.py (+12/-7)
To merge this branch: bzr merge lp:~aptdaemon-developers/aptdaemon/lintian-profiles
Reviewer Review Type Date Requested Status
Michael Vogt Approve
Niels Thykier Pending
Review via email: mp+109333@code.launchpad.net

Description of the change

Use lintian profiles instead of the tag files

To post a comment you must log in.
840. By Sebastian Heinlein

Set $HOME to a temporary dir before executing lintian

Setting LINTIAN_INTERNAL_TESTSUITE doesn't load any custom profiles
from /etc and would not allow admins to modify the installed policy easily

841. By Sebastian Heinlein

Push local changes

842. By Sebastian Heinlein

Merge with trunk

843. By Sebastian Heinlein

Update NEWS

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

This looks fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2012-06-11 06:38:54 +0000
3+++ NEWS 2012-06-11 06:52:21 +0000
4@@ -8,6 +8,9 @@
5
6 - Support more PackageKit transactions (InstallSignature, RepoEnable)
7
8+ - Use lintian profiles instead of tag files (separat profiles for Debian
9+ and Ubuntu are available). Thanks to Niels Thykier.
10+
11 * API changes:
12
13 - aptdaemon.test.TestCase has now a start_keyserver() method to fake
14
15=== modified file 'aptdaemon/progress.py'
16--- aptdaemon/progress.py 2012-06-07 04:59:57 +0000
17+++ aptdaemon/progress.py 2012-06-11 06:52:21 +0000
18@@ -20,8 +20,11 @@
19 import logging
20 import os
21 import re
22+import shutil
23 import signal
24+import subprocess
25 import sys
26+import tempfile
27 import termios
28 import time
29 import traceback
30@@ -609,6 +612,48 @@
31 return False
32
33
34+class DaemonLintianProgress(DaemonForkProgress):
35+
36+ """Performs a lintian call."""
37+
38+ def start_update(self):
39+ DaemonForkProgress.start_update(self)
40+ self.tempdir = os.getenv("APTDAEMON_LINTIAN_HOME",
41+ tempfile.mkdtemp(prefix="aptdaemon-lintian-"))
42+
43+ def finish_update(self):
44+ DaemonForkProgress.finish_update(self)
45+ if not os.getenv("APTDAEMON_LINTIAN_HOME"):
46+ try:
47+ shutil.rmtree(self.tempdir)
48+ except AttributeError:
49+ pass
50+
51+ def _child(self, path):
52+ # Avoid running lintian as root
53+ os.setuid(self.transaction.uid)
54+ # FIXME: Should be handled by lintian ideally
55+ if subprocess.check_call(["/usr/bin/dpkg-vendor",
56+ "--derives-from", "Ubuntu"]) == 0:
57+ profile = "ubuntu/aptdaemon"
58+ else:
59+ profile = "debian/aptdaemon"
60+ # By default lintian tries to load profiles from
61+ # $HOME/.lintian/profiles. This would allow an user to inject
62+ # a relaxed profile.
63+ # Currently the loading of custom profiles can only disabled by
64+ # setting the LINTIAN_INTERNAL_TESTSUITE env.
65+ # But then also profiles from /etc/lintian would be skipped
66+ # See, LP# 1006327
67+ os.environ["HOME"] = self.tempdir
68+
69+ lintian_path = apt_pkg.config.find_file("Dir::Bin::Lintian",
70+ "/usr/bin/lintian")
71+ os.execlp(lintian_path, lintian_path, "--no-cfg", "--fail-on-warnings",
72+ "--profile", profile, path)
73+ os._exit(1)
74+
75+
76 class DaemonInstallProgress(DaemonForkProgress):
77
78 """Progress to execute APT package operations in a child process."""
79
80=== modified file 'aptdaemon/worker.py'
81--- aptdaemon/worker.py 2012-06-08 05:26:16 +0000
82+++ aptdaemon/worker.py 2012-06-11 06:52:21 +0000
83@@ -56,6 +56,7 @@
84 DaemonDpkgInstallProgress, \
85 DaemonDpkgReconfigureProgress, \
86 DaemonDpkgRecoverProgress, \
87+ DaemonLintianProgress, \
88 DaemonForkProgress
89
90 log = logging.getLogger("AptDaemon.Worker")
91@@ -596,7 +597,7 @@
92 log.info("Installing local package file: %s", path)
93 # Check if the dpkg can be installed at all
94 trans.status = STATUS_RESOLVING_DEP
95- deb = self._check_deb_file(path, force, trans.uid)
96+ deb = self._check_deb_file(trans, path, force)
97 # Check for required changes and apply them before
98 (install, remove, unauth) = deb.required_changes
99 self._call_plugins("modify_cache_after")
100@@ -1172,57 +1173,23 @@
101
102 return depends, required_download, required_space, unauthenticated
103
104- def _check_deb_file(self, path, force, uid):
105+ def _check_deb_file(self, trans, path, force):
106 """Perform some basic checks for the Debian package.
107
108 :param trans: The transaction instance.
109
110 :returns: An apt.debfile.Debfile instance.
111 """
112- #FIXME: Unblock lintian call
113 if not os.path.isfile(path):
114 raise TransactionFailed(ERROR_UNREADABLE_PACKAGE_FILE, path)
115 if not force and os.path.isfile("/usr/bin/lintian"):
116- tags_dir = os.path.join(apt_pkg.config.find_dir("Dir"),
117- "usr", "share", "aptdaemon")
118- try:
119- distro = platform.dist()[0]
120- except KeyError:
121- distro = None
122- else:
123- tags_file = os.path.join(tags_dir,
124- "lintian-nonfatal.tags.%s" % distro)
125- tags_fatal_file = os.path.join(tags_dir,
126- "lintian-fatal.tags.%s" % distro)
127- if not distro or not os.path.exists(tags_file):
128- log.debug("Using default lintian tags file")
129- tags_file = os.path.join(tags_dir, "lintian-nonfatal.tags")
130- if not distro or not os.path.exists(tags_fatal_file):
131- log.debug("Using default lintian fatal tags file")
132- tags_fatal_file = os.path.join(tags_dir, "lintian-fatal.tags")
133- # Run linitan as the user who initiated the transaction
134- # Once with non fatal checks and a second time with the fatal
135- # checks which are not allowed to be overriden
136- nonfatal_args = ["/usr/bin/lintian", "--tags-from-file",
137- tags_file, path]
138- fatal_args = ["/usr/bin/lintian", "--tags-from-file",
139- tags_fatal_file, "--no-override", path]
140- for lintian_args in (nonfatal_args, fatal_args):
141- proc = subprocess.Popen(lintian_args,
142- stderr=subprocess.STDOUT,
143- stdout=subprocess.PIPE, close_fds=True,
144- preexec_fn=lambda: os.setuid(uid))
145- while proc.poll() is None:
146- self._iterate_mainloop()
147- time.sleep(0.05)
148- #FIXME: Add an error to catch return state 2 (failure)
149- if proc.returncode == 1:
150- stdout = proc.stdout.read()
151- stdout.decode(sys.stdin.encoding or "UTF-8",
152- errors="replace")
153- raise TransactionFailed(ERROR_INVALID_PACKAGE_FILE,
154- "Lintian check results for %s:"
155- "\n%s" % (path, stdout))
156+ with DaemonLintianProgress(trans) as progress:
157+ progress.run(path)
158+ #FIXME: Add an error to catch return state 2 (failure)
159+ if progress._child_exit != 0:
160+ raise TransactionFailed(ERROR_INVALID_PACKAGE_FILE,
161+ "Lintian check results for %s:"
162+ "\n%s" % (path, progress.output))
163 try:
164 deb = apt.debfile.DebPackage(path, self._cache)
165 except IOError:
166
167=== added directory 'data/lintian'
168=== removed file 'data/lintian-fatal.tags'
169--- data/lintian-fatal.tags 2011-04-06 07:56:33 +0000
170+++ data/lintian-fatal.tags 1970-01-01 00:00:00 +0000
171@@ -1,66 +0,0 @@
172-# This file lists all tags that cause an automatic reject on upload and cannot
173-# be overridden. It is based on the data file retrieved from
174-# http://ftp-master.debian.org/static/lintian.tags
175-#
176-# Last updated: 2011-01-26
177-
178-FSSTND-dir-in-usr
179-FSSTND-dir-in-var
180-bad-package-name
181-bad-relation
182-bad-version-number
183-binary-file-compressed-with-upx
184-binary-in-etc
185-build-info-in-binary-control-file-section
186-control-file-has-bad-owner
187-control-file-has-bad-permissions
188-control-interpreter-in-usr-local
189-copyright-file-compressed
190-copyright-file-is-symlink
191-copyright-refers-to-incorrect-directory
192-copyright-refers-to-old-directory
193-debian-control-file-uses-obsolete-national-encoding
194-debian-control-with-duplicate-fields
195-debian-rules-missing-required-target
196-debian-rules-not-a-makefile
197-description-is-dh_make-template
198-description-synopsis-is-empty
199-dir-or-file-in-mnt
200-# Allow third party packages to make use of /opt
201-# dir-or-file-in-opt
202-dir-or-file-in-srv
203-dir-or-file-in-tmp
204-extended-description-is-empty
205-file-in-etc-not-marked-as-conffile
206-file-in-usr-marked-as-conffile
207-forbidden-postrm-interpreter
208-library-in-debug-or-profile-should-not-be-stripped
209-magic-arch-in-arch-list
210-maintainer-address-is-on-localhost
211-maintainer-address-malformed
212-maintainer-address-missing
213-maintainer-name-missing
214-maintainer-script-removes-device-files
215-malformed-deb-archive
216-missing-dependency-on-perlapi
217-no-architecture-field
218-no-copyright-file
219-no-maintainer-field
220-no-package-name
221-no-source-field
222-no-version-field
223-not-allowed-control-file
224-old-style-copyright-file
225-package-contains-ancient-file
226-package-has-no-description
227-package-installs-python-bytecode
228-package-not-lowercase
229-package-uses-local-diversion
230-section-is-dh_make-template
231-source-field-does-not-match-pkg-name
232-symlink-has-too-many-up-segments
233-too-many-architectures
234-uploader-address-is-on-localhost
235-uploader-address-malformed
236-uploader-name-missing
237-usr-share-doc-symlink-to-foreign-package
238
239=== removed file 'data/lintian-nonfatal.tags'
240--- data/lintian-nonfatal.tags 2011-04-15 07:50:24 +0000
241+++ data/lintian-nonfatal.tags 1970-01-01 00:00:00 +0000
242@@ -1,25 +0,0 @@
243-# This file lists all tags that cause an automatic reject on upload but can
244-# be overridden (nonfatal tags). It is based on the data file retrieved from
245-# http://ftp-master.debian.org/static/lintian.tags
246-#
247-# Last updated: 2011-01-26
248-
249-arch-dependent-file-in-usr-share
250-arch-independent-package-contains-binary-or-object
251-binary-or-shlib-defines-rpath
252-binary-with-bad-dynamic-table
253-control-interpreter-without-depends
254-copyright-contains-dh_make-todo-boilerplate
255-dir-or-file-in-var-www
256-embedded-library
257-missing-build-dependency
258-# For LSB packages it is sufficient to depend on lsb-base
259-# missing-dependency-on-libc
260-mknod-in-maintainer-script
261-no-shlibs-control-file
262-non-etc-file-marked-as-conffile
263-package-contains-info-dir-file
264-preinst-interpreter-without-predepends
265-statically-linked-binary
266-usr-share-doc-symlink-without-dependency
267-wrong-file-owner-uid-or-gid
268
269=== added directory 'data/lintian/debian'
270=== added file 'data/lintian/debian/aptdaemon.profile'
271--- data/lintian/debian/aptdaemon.profile 1970-01-01 00:00:00 +0000
272+++ data/lintian/debian/aptdaemon.profile 2012-06-11 06:52:21 +0000
273@@ -0,0 +1,7 @@
274+# The default profile installing local software packages used by aptdaemon
275+Profile: debian/aptdaemon
276+Extends: debian/ftp-master-auto-reject
277+Disable-Tags:
278+ dir-or-file-in-opt,
279+ missing-dependency-on-libc,
280+ statically-linked-binary
281
282=== added directory 'data/lintian/ubuntu'
283=== added file 'data/lintian/ubuntu/aptdaemon.profile'
284--- data/lintian/ubuntu/aptdaemon.profile 1970-01-01 00:00:00 +0000
285+++ data/lintian/ubuntu/aptdaemon.profile 2012-06-11 06:52:21 +0000
286@@ -0,0 +1,43 @@
287+# The default profile installing local software packages used by aptdaemon
288+Profile: ubuntu/aptdaemon
289+Extends: debian/aptdaemon
290+Disable-Tags:
291+ FSSTND-dir-in-usr,
292+ FSSTND-dir-in-var,
293+ arch-dependent-file-in-usr-share,
294+ binary-file-compressed-with-upx,
295+ binary-or-shlib-defines-rpath,
296+ control-interpreter-in-usr-local,
297+ copyright-contains-dh_make-todo-boilerplate,
298+ copyright-file-compressed,
299+ copyright-file-is-symlink,
300+ copyright-refers-to-incorrect-directory,
301+ copyright-refers-to-old-directory,
302+ debian-rules-missing-required-target,
303+ debian-rules-not-a-makefile,
304+ description-is-dh_make-template,
305+ description-synopsis-is-empty,
306+ dir-or-file-in-srv,
307+ dir-or-file-in-var-www,
308+ embedded-library,
309+ extended-description-is-empty,
310+ file-in-usr-marked-as-conffile,
311+ install-info-used-in-maintainer-script,
312+ library-in-debug-or-profile-should-not-be-stripped,
313+ magic-arch-in-arch-list,
314+ missing-build-dependency,
315+ missing-pre-dependency-on-multiarch-support,
316+ mknod-in-maintainer-script,
317+ no-architecture-field,
318+ no-copyright-file,
319+ no-maintainer-field,
320+ no-shlibs-control-file,
321+ package-installs-python-bytecode,
322+ section-is-dh_make-template,
323+ statically-linked-binary,
324+ udeb-uses-unsupported-compression-for-data-tarball,
325+ uploader-address-is-on-localhost,
326+ uploader-address-malformed,
327+ uploader-name-missing,
328+ usr-share-doc-symlink-to-foreign-package,
329+ usr-share-doc-symlink-without-dependency,
330
331=== modified file 'setup.py'
332--- setup.py 2012-06-04 07:28:07 +0000
333+++ setup.py 2012-06-11 06:52:21 +0000
334@@ -46,11 +46,13 @@
335 ["data/20dbus"]),
336 ("share/apport/package-hooks",
337 ["apport/aptdaemon.py"]),
338- ("share/aptdaemon",
339- glob.glob("data/lintian-*fatal.tags*")),
340 ("share/dbus-1/system-services/",
341 ["data/org.debian.apt.service",
342 "data/org.freedesktop.PackageKit.service"]),
343+ ("share/lintian/profiles/ubuntu/",
344+ ["data/lintian/ubuntu/aptdaemon.profile"]),
345+ ("share/lintian/profiles/debian/",
346+ ["data/lintian/debian/aptdaemon.profile"]),
347 ("share/man/man1",
348 ["doc/aptd.1", "doc/aptdcon.1"]),
349 ("share/man/man7",
350
351=== modified file 'tests/test_worker.py'
352--- tests/test_worker.py 2012-06-04 09:17:34 +0000
353+++ tests/test_worker.py 2012-06-11 06:52:21 +0000
354@@ -288,15 +288,19 @@
355 def test_install_file(self):
356 """Test the installation of a local package file."""
357 # add custom lintian file
358- target = os.path.join(self.chroot.path, "usr", "share", "aptdaemon")
359- os.makedirs(target)
360- for tags_file in glob.glob(os.path.join(aptdaemon.test.get_tests_dir(),
361- "../data/lintian*tags*")):
362- shutil.copy(tags_file, target)
363+ os.environ["APTDAEMON_LINTIAN_HOME"] = self.chroot.path
364+ self.addCleanup(os.putenv, "APTDAEMON_LINTIAN_HOME", "")
365+ os.makedirs(os.path.join(self.chroot.path, ".lintian/profiles/"))
366+ for profile in glob.glob(os.path.join(aptdaemon.test.get_tests_dir(),
367+ "../data/lintian/*")):
368+ shutil.copytree(profile,
369+ os.path.join(self.chroot.path,
370+ ".lintian/profiles",
371+ os.path.basename(profile)))
372 # test
373 self.chroot.add_test_repository()
374- pkg = os.path.join(
375- REPO_PATH, "silly-depend-base-lintian-broken_0.1-0_all.deb")
376+ pkg = os.path.join(REPO_PATH,
377+ "silly-depend-base-lintian-broken_0.1-0_all.deb")
378 trans = Transaction(None, enums.ROLE_INSTALL_FILE, self.queue,
379 os.getpid(), os.getuid(), sys.argv[0],
380 "org.debian.apt.test", connect=False,
381@@ -304,6 +308,7 @@
382 "force": False})
383 self.worker.simulate(trans)
384 self.loop.run()
385+ self.assertTrue("wrong-file-owner-uid-or-gid" in trans.error.details)
386 self.assertEqual(trans.error.code, enums.ERROR_INVALID_PACKAGE_FILE,
387 "Lintian failed to detect a broken package")
388 # Now allow to install invalid packages

Subscribers

People subscribed via source and target branches

to status/vote changes: