Merge lp:~aptdaemon-developers/aptdaemon/lintian-profiles into lp:aptdaemon
- lintian-profiles
- Merge into main
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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Vogt | Approve | ||
Niels Thykier | Pending | ||
Review via email: mp+109333@code.launchpad.net |
Commit message
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
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 |
This looks fine.