Merge lp:~cjwatson/launchpad/orig-tarball-signatures into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18083
Proposed branch: lp:~cjwatson/launchpad/orig-tarball-signatures
Merge into: lp:launchpad
Diff against target: 480 lines (+158/-41)
6 files modified
lib/lp/archiveuploader/dscfile.py (+52/-9)
lib/lp/archiveuploader/tests/test_dscfile.py (+59/-27)
lib/lp/archiveuploader/tests/test_utils.py (+22/-1)
lib/lp/archiveuploader/utils.py (+10/-2)
lib/lp/registry/interfaces/sourcepackage.py (+11/-0)
lib/lp/soyuz/model/files.py (+4/-2)
To merge this branch: bzr merge lp:~cjwatson/launchpad/orig-tarball-signatures
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+296155@code.launchpad.net

Commit message

Handle original tarball signatures in source packages.

Description of the change

Handle original tarball signatures in source packages.

Some more upload processor tests should exist, but can't quite yet because we first need a dpkg with the necessary cherry-picks to be able to unpack these packages.

Component tarball signature checks could be more accurate (e.g. test that all signatures have a matching tarball), but that was a bit fiddly to wedge into the file checker abstraction and doesn't seem vitally important.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/archiveuploader/dscfile.py'
2--- lib/lp/archiveuploader/dscfile.py 2016-03-18 14:12:07 +0000
3+++ lib/lp/archiveuploader/dscfile.py 2016-06-01 02:29:15 +0000
4@@ -50,6 +50,7 @@
5 parse_maintainer_bytes,
6 ParseMaintError,
7 re_is_component_orig_tar_ext,
8+ re_is_component_orig_tar_ext_sig,
9 re_issource,
10 re_valid_pkg_name,
11 re_valid_version,
12@@ -441,7 +442,10 @@
13 if (self.policy.archive.purpose == ArchivePurpose.PPA and
14 determine_source_file_type(filename) in (
15 SourcePackageFileType.ORIG_TARBALL,
16- SourcePackageFileType.COMPONENT_ORIG_TARBALL)):
17+ SourcePackageFileType.COMPONENT_ORIG_TARBALL,
18+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE,
19+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE,
20+ )):
21 archives = [self.policy.archive, self.policy.distro.main_archive]
22 else:
23 archives = [self.policy.archive]
24@@ -470,10 +474,12 @@
25 file_type_counts = {
26 SourcePackageFileType.DIFF: 0,
27 SourcePackageFileType.ORIG_TARBALL: 0,
28+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 0,
29 SourcePackageFileType.DEBIAN_TARBALL: 0,
30 SourcePackageFileType.NATIVE_TARBALL: 0,
31 }
32 component_orig_tar_counts = {}
33+ component_orig_tar_signature_counts = {}
34 bzip2_count = 0
35 xz_count = 0
36 files_missing = False
37@@ -492,6 +498,15 @@
38 if component not in component_orig_tar_counts:
39 component_orig_tar_counts[component] = 0
40 component_orig_tar_counts[component] += 1
41+ elif (
42+ file_type ==
43+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE):
44+ # Split the count by component name.
45+ component = re_is_component_orig_tar_ext_sig.match(
46+ get_source_file_extension(sub_dsc_file.filename)).group(1)
47+ if component not in component_orig_tar_signature_counts:
48+ component_orig_tar_signature_counts[component] = 0
49+ component_orig_tar_signature_counts[component] += 1
50 else:
51 file_type_counts[file_type] += 1
52
53@@ -552,7 +567,7 @@
54
55 for error in file_checker(
56 self.filename, file_type_counts, component_orig_tar_counts,
57- bzip2_count, xz_count):
58+ component_orig_tar_signature_counts, bzip2_count, xz_count):
59 yield error
60
61 if files_missing:
62@@ -791,12 +806,14 @@
63 return open(changelog_file, 'r').read()
64
65
66-def check_format_1_0_files(filename, file_type_counts, component_counts,
67+def check_format_1_0_files(filename, file_type_counts,
68+ component_counts, component_signature_counts,
69 bzip2_count, xz_count):
70 """Check that the given counts of each file type suit format 1.0.
71
72 A 1.0 source must be native (with only one tar.gz), or have an orig.tar.gz
73- and a diff.gz. It cannot use bzip2 or xz compression.
74+ and a diff.gz. It cannot use bzip2 or xz compression. If it has an
75+ orig.tar.gz, it may have an orig.tar.gz.asc signature.
76 """
77 if bzip2_count > 0:
78 yield UploadError(
79@@ -811,11 +828,20 @@
80 {
81 SourcePackageFileType.NATIVE_TARBALL: 1,
82 SourcePackageFileType.ORIG_TARBALL: 0,
83+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 0,
84 SourcePackageFileType.DEBIAN_TARBALL: 0,
85 SourcePackageFileType.DIFF: 0,
86 },
87 {
88 SourcePackageFileType.ORIG_TARBALL: 1,
89+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 0,
90+ SourcePackageFileType.DIFF: 1,
91+ SourcePackageFileType.NATIVE_TARBALL: 0,
92+ SourcePackageFileType.DEBIAN_TARBALL: 0,
93+ },
94+ {
95+ SourcePackageFileType.ORIG_TARBALL: 1,
96+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 1,
97 SourcePackageFileType.DIFF: 1,
98 SourcePackageFileType.NATIVE_TARBALL: 0,
99 SourcePackageFileType.DEBIAN_TARBALL: 0,
100@@ -823,14 +849,15 @@
101 ]
102
103 if (file_type_counts not in valid_file_type_counts or
104- len(component_counts) > 0):
105+ len(component_counts) > 0 or len(component_signature_counts) > 0):
106 yield UploadError(
107 "%s: must have exactly one tar.gz, or an orig.tar.gz and diff.gz"
108 % filename)
109
110
111 def check_format_3_0_native_files(filename, file_type_counts,
112- component_counts, bzip2_count, xz_count):
113+ component_counts, component_signature_counts,
114+ bzip2_count, xz_count):
115 """Check that the given counts of each file type suit format 3.0 (native).
116
117 A 3.0 (native) source must have only one tar.*. Any of gzip, bzip2, and
118@@ -841,28 +868,39 @@
119 {
120 SourcePackageFileType.NATIVE_TARBALL: 1,
121 SourcePackageFileType.ORIG_TARBALL: 0,
122+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 0,
123 SourcePackageFileType.DEBIAN_TARBALL: 0,
124 SourcePackageFileType.DIFF: 0,
125 },
126 ]
127
128 if (file_type_counts not in valid_file_type_counts or
129- len(component_counts) > 0):
130+ len(component_counts) > 0 or len(component_signature_counts) > 0):
131 yield UploadError("%s: must have only a tar.*." % filename)
132
133
134 def check_format_3_0_quilt_files(filename, file_type_counts,
135- component_counts, bzip2_count, xz_count):
136+ component_counts, component_signature_counts,
137+ bzip2_count, xz_count):
138 """Check that the given counts of each file type suit format 3.0 (native).
139
140 A 3.0 (quilt) source must have exactly one orig.tar.*, one debian.tar.*,
141 and at most one orig-COMPONENT.tar.* for each COMPONENT. Any of gzip,
142- bzip2, and xz compression are permissible.
143+ bzip2, and xz compression are permissible. It may have orig.tar.*.asc
144+ or orig-COMPONENT.tar.* signatures.
145 """
146
147 valid_file_type_counts = [
148 {
149 SourcePackageFileType.ORIG_TARBALL: 1,
150+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 0,
151+ SourcePackageFileType.DEBIAN_TARBALL: 1,
152+ SourcePackageFileType.NATIVE_TARBALL: 0,
153+ SourcePackageFileType.DIFF: 0,
154+ },
155+ {
156+ SourcePackageFileType.ORIG_TARBALL: 1,
157+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE: 1,
158 SourcePackageFileType.DEBIAN_TARBALL: 1,
159 SourcePackageFileType.NATIVE_TARBALL: 0,
160 SourcePackageFileType.DIFF: 0,
161@@ -879,6 +917,11 @@
162 yield UploadError(
163 "%s: has more than one orig-%s.tar.*."
164 % (filename, component))
165+ for component in component_signature_counts:
166+ if component_signature_counts[component] > 1:
167+ yield UploadError(
168+ "%s: has more than one orig-%s.tar.*.asc."
169+ % (filename, component))
170
171
172 format_to_file_checker_map = {
173
174=== modified file 'lib/lp/archiveuploader/tests/test_dscfile.py'
175--- lib/lp/archiveuploader/tests/test_dscfile.py 2016-02-05 16:51:12 +0000
176+++ lib/lp/archiveuploader/tests/test_dscfile.py 2016-06-01 02:29:15 +0000
177@@ -41,6 +41,7 @@
178
179
180 ORIG_TARBALL = SourcePackageFileType.ORIG_TARBALL
181+ORIG_TARBALL_SIGNATURE = SourcePackageFileType.ORIG_TARBALL_SIGNATURE
182 DEBIAN_TARBALL = SourcePackageFileType.DEBIAN_TARBALL
183 NATIVE_TARBALL = SourcePackageFileType.NATIVE_TARBALL
184 DIFF = SourcePackageFileType.DIFF
185@@ -229,21 +230,24 @@
186
187 class BaseTestSourceFileVerification(TestCase):
188
189- def assertErrorsForFiles(self, expected, files, components={},
190+ def assertErrorsForFiles(self, expected, files,
191+ components={}, component_signatures={},
192 bzip2_count=0, xz_count=0):
193 """Check problems with the given set of files for the given format.
194
195 :param expected: a list of expected errors, as strings.
196 :param format: the `SourcePackageFormat` to check against.
197 :param files: a dict mapping `SourcePackageFileType`s to counts.
198- :param components: a dict mapping orig component tarball components
199- to counts.
200+ :param components: a dict mapping orig component tarballs to counts.
201+ :param component_signatures: a dict mapping orig component tarball
202+ signatures to counts.
203 :param bzip2_count: number of files using bzip2 compression.
204 :param xz_count: number of files using xz compression.
205 """
206 full_files = {
207 NATIVE_TARBALL: 0,
208 ORIG_TARBALL: 0,
209+ ORIG_TARBALL_SIGNATURE: 0,
210 DIFF: 0,
211 DEBIAN_TARBALL: 0,
212 }
213@@ -251,20 +255,23 @@
214 self.assertEquals(
215 expected,
216 [str(e) for e in format_to_file_checker_map[self.format](
217- 'foo_1.dsc', full_files, components, bzip2_count, xz_count)])
218+ 'foo_1.dsc', full_files, components, component_signatures,
219+ bzip2_count, xz_count)])
220
221- def assertFilesOK(self, files, components={}, bzip2_count=0, xz_count=0):
222+ def assertFilesOK(self, files, components={}, component_signatures={},
223+ bzip2_count=0, xz_count=0):
224 """Check that the given set of files is OK for the given format.
225
226 :param format: the `SourcePackageFormat` to check against.
227 :param files: a dict mapping `SourcePackageFileType`s to counts.
228- :param components: a dict mapping orig component tarball components
229- to counts.
230+ :param components: a dict mapping orig component tarball to counts.
231+ :param component_signatures: a dict mapping orig component tarball
232+ signatures to counts.
233 :param bzip2_count: number of files using bzip2 compression.
234 :param xz_count: number of files using xz compression.
235 """
236 self.assertErrorsForFiles(
237- [], files, components, bzip2_count, xz_count)
238+ [], files, components, component_signatures, bzip2_count, xz_count)
239
240
241 class Test10SourceFormatVerification(BaseTestSourceFileVerification):
242@@ -280,6 +287,11 @@
243 # A 1.0 source can contain an original tarball and a Debian diff
244 self.assertFilesOK({ORIG_TARBALL: 1, DIFF: 1})
245
246+ def testFormat10DebianWithOrigSignature(self):
247+ # A 1.0 source can contain an original tarball signature.
248+ self.assertFilesOK(
249+ {ORIG_TARBALL: 1, ORIG_TARBALL_SIGNATURE: 1, DIFF: 1})
250+
251 def testFormat10Native(self):
252 # A 1.0 source can contain a native tarball.
253 self.assertFilesOK({NATIVE_TARBALL: 1})
254@@ -287,25 +299,33 @@
255 def testFormat10CannotHaveWrongFiles(self):
256 # A 1.0 source cannot have a combination of native and
257 # non-native files, and cannot have just one of the non-native
258- # files.
259+ # files or an original tarball signature without an original
260+ # tarball.
261 for combination in (
262- {DIFF: 1}, {ORIG_TARBALL: 1}, {ORIG_TARBALL: 1, DIFF: 1,
263- NATIVE_TARBALL: 1}):
264+ {DIFF: 1}, {ORIG_TARBALL: 1}, {ORIG_TARBALL_SIGNATURE: 1},
265+ {ORIG_TARBALL_SIGNATURE: 1, DIFF: 1}):
266+ {ORIG_TARBALL: 1, DIFF: 1, NATIVE_TARBALL: 1},
267 self.assertErrorsForFiles([self.wrong_files_error], combination)
268
269 # A 1.0 source with component tarballs is invalid.
270 self.assertErrorsForFiles(
271- [self.wrong_files_error], {ORIG_TARBALL: 1, DIFF: 1}, {'foo': 1})
272+ [self.wrong_files_error], {ORIG_TARBALL: 1, DIFF: 1},
273+ components={'foo': 1})
274+
275+ # A 1.0 source with component tarball signatures is invalid.
276+ self.assertErrorsForFiles(
277+ [self.wrong_files_error], {ORIG_TARBALL: 1, DIFF: 1},
278+ component_signatures={'foo': 1})
279
280 def testFormat10CannotUseBzip2(self):
281 # 1.0 sources cannot use bzip2 compression.
282 self.assertErrorsForFiles(
283- [self.bzip2_error], {NATIVE_TARBALL: 1}, {}, 1, 0)
284+ [self.bzip2_error], {NATIVE_TARBALL: 1}, {}, bzip2_count=1)
285
286 def testFormat10CannotUseXz(self):
287 # 1.0 sources cannot use xz compression.
288 self.assertErrorsForFiles(
289- [self.xz_error], {NATIVE_TARBALL: 1}, {}, 0, 1)
290+ [self.xz_error], {NATIVE_TARBALL: 1}, {}, xz_count=1)
291
292
293 class Test30QuiltSourceFormatVerification(BaseTestSourceFileVerification):
294@@ -318,14 +338,21 @@
295
296 def testFormat30Quilt(self):
297 # A 3.0 (quilt) source must contain an orig tarball and a debian
298- # tarball. It may also contain at most one component tarball for
299- # each component, and can use gzip, bzip2, or xz compression.
300+ # tarball. It may also contain at most one component tarball (with
301+ # optional signature) for each component, and can use gzip, bzip2,
302+ # or xz compression.
303 for components in ({}, {'foo': 1}, {'foo': 1, 'bar': 1}):
304- for bzip2_count in (0, 1):
305- for xz_count in (0, 1):
306- self.assertFilesOK(
307- {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1}, components,
308- bzip2_count, xz_count)
309+ for component_signatures in ({}, components):
310+ for orig_signature in (0, 1):
311+ for bzip2_count in (0, 1):
312+ for xz_count in (0, 1):
313+ self.assertFilesOK(
314+ {ORIG_TARBALL: 1,
315+ ORIG_TARBALL_SIGNATURE: orig_signature,
316+ DEBIAN_TARBALL: 1},
317+ components=components,
318+ component_signatures=component_signatures,
319+ bzip2_count=bzip2_count, xz_count=xz_count)
320
321 def testFormat30QuiltCannotHaveConflictingComponentTarballs(self):
322 # Multiple conflicting tarballs for a single component are
323@@ -352,19 +379,24 @@
324 # 3.0 (native) sources must contain just a native tarball. They
325 # may use gzip, bzip2, or xz compression.
326 for bzip2_count in (0, 1):
327- self.assertFilesOK({NATIVE_TARBALL: 1}, {},
328- bzip2_count, 0)
329- self.assertFilesOK({NATIVE_TARBALL: 1}, {}, 0, 1)
330+ self.assertFilesOK({NATIVE_TARBALL: 1}, bzip2_count=bzip2_count)
331+ self.assertFilesOK({NATIVE_TARBALL: 1}, xz_count=1)
332
333 def testFormat30NativeCannotHaveWrongFiles(self):
334 # 3.0 (quilt) sources may not have a diff, Debian tarball, orig
335- # tarball, or any component tarballs.
336- for filetype in (DIFF, DEBIAN_TARBALL, ORIG_TARBALL):
337+ # tarball, orig tarball signature, or any component tarballs.
338+ for filetype in (
339+ DIFF, DEBIAN_TARBALL, ORIG_TARBALL, ORIG_TARBALL_SIGNATURE):
340 self.assertErrorsForFiles(
341 [self.wrong_files_error], {NATIVE_TARBALL: 1, filetype: 1})
342 # A 3.0 (native) source with component tarballs is invalid.
343 self.assertErrorsForFiles(
344- [self.wrong_files_error], {NATIVE_TARBALL: 1}, {'foo': 1})
345+ [self.wrong_files_error], {NATIVE_TARBALL: 1},
346+ components={'foo': 1})
347+ # A 3.0 (native) source with component tarball signatures is invalid.
348+ self.assertErrorsForFiles(
349+ [self.wrong_files_error], {NATIVE_TARBALL: 1},
350+ component_signatures={'foo': 1})
351
352
353 class UnpackedDirTests(TestCase):
354
355=== modified file 'lib/lp/archiveuploader/tests/test_utils.py'
356--- lib/lp/archiveuploader/tests/test_utils.py 2015-07-29 07:11:41 +0000
357+++ lib/lp/archiveuploader/tests/test_utils.py 2016-06-01 02:29:15 +0000
358@@ -1,6 +1,6 @@
359 #!/usr/bin/python
360 #
361-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
362+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
363 # GNU Affero General Public License version 3 (see the file LICENSE).
364
365 # arch-tag: 90e6eb79-83a2-47e8-9f8b-3c687079c923
366@@ -87,6 +87,27 @@
367 determine_source_file_type('foo_1.0.tar.xz'),
368 SourcePackageFileType.NATIVE_TARBALL)
369
370+ # (Component) original tarball signatures are detected for any
371+ # supported compression method.
372+ self.assertEquals(
373+ determine_source_file_type('foo_1.0.orig.tar.gz.asc'),
374+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE)
375+ self.assertEquals(
376+ determine_source_file_type('foo_1.0.orig.tar.bz2.asc'),
377+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE)
378+ self.assertEquals(
379+ determine_source_file_type('foo_1.0.orig.tar.xz.asc'),
380+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE)
381+ self.assertEquals(
382+ determine_source_file_type('foo_1.0.orig-foo.tar.gz.asc'),
383+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE)
384+ self.assertEquals(
385+ determine_source_file_type('foo_1.0.orig-bar.tar.bz2.asc'),
386+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE)
387+ self.assertEquals(
388+ determine_source_file_type('foo_1.0.orig-bar.tar.xz.asc'),
389+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE)
390+
391 self.assertEquals(None, determine_source_file_type('foo_1.0'))
392 self.assertEquals(None, determine_source_file_type('foo_1.0.blah.gz'))
393
394
395=== modified file 'lib/lp/archiveuploader/utils.py'
396--- lib/lp/archiveuploader/utils.py 2015-07-29 07:01:04 +0000
397+++ lib/lp/archiveuploader/utils.py 2016-06-01 02:29:15 +0000
398@@ -1,4 +1,4 @@
399-# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
400+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
401 # GNU Affero General Public License version 3 (see the file LICENSE).
402
403 """Archive uploader utilities."""
404@@ -19,6 +19,7 @@
405 're_isadeb',
406 're_issource',
407 're_is_component_orig_tar_ext',
408+ 're_is_component_orig_tar_ext_sig',
409 're_no_epoch',
410 're_no_revision',
411 're_valid_version',
412@@ -67,12 +68,15 @@
413 re_isadeb = re.compile(r"(.+?)_(.+?)_(.+)\.(u?d?deb)$")
414
415 source_file_exts = [
416- 'orig(?:-.+)?\.tar\.(?:gz|bz2|xz)', 'diff.gz',
417+ 'orig(?:-.+)?\.tar\.(?:gz|bz2|xz)(?:\.asc)?', 'diff.gz',
418 '(?:debian\.)?tar\.(?:gz|bz2|xz)', 'dsc']
419 re_issource = re.compile(
420 r"([^_]+)_(.+?)\.(%s)" % "|".join(ext for ext in source_file_exts))
421 re_is_component_orig_tar_ext = re.compile(r"^orig-(.+).tar.(?:gz|bz2|xz)$")
422+re_is_component_orig_tar_ext_sig = re.compile(
423+ r"^orig-(.+).tar.(?:gz|bz2|xz)\.asc$")
424 re_is_orig_tar_ext = re.compile(r"^orig.tar.(?:gz|bz2|xz)$")
425+re_is_orig_tar_ext_sig = re.compile(r"^orig.tar.(?:gz|bz2|xz)\.asc$")
426 re_is_debian_tar_ext = re.compile(r"^debian.tar.(?:gz|bz2|xz)$")
427 re_is_native_tar_ext = re.compile(r"^tar.(?:gz|bz2|xz)$")
428
429@@ -115,6 +119,10 @@
430 return SourcePackageFileType.DEBIAN_TARBALL
431 elif re_is_native_tar_ext.match(extension):
432 return SourcePackageFileType.NATIVE_TARBALL
433+ elif re_is_orig_tar_ext_sig.match(extension):
434+ return SourcePackageFileType.ORIG_TARBALL_SIGNATURE
435+ elif re_is_component_orig_tar_ext_sig.match(extension):
436+ return SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE
437 else:
438 return None
439
440
441=== modified file 'lib/lp/registry/interfaces/sourcepackage.py'
442--- lib/lp/registry/interfaces/sourcepackage.py 2015-11-24 01:44:28 +0000
443+++ lib/lp/registry/interfaces/sourcepackage.py 2016-06-01 02:29:15 +0000
444@@ -411,6 +411,17 @@
445
446 This is only part of the 3.0 (quilt) source package format.""")
447
448+ ORIG_TARBALL_SIGNATURE = DBItem(9, """
449+ Orig Tarball Signature
450+
451+ This file is a detached signature for an Ubuntu "orig" file.""")
452+
453+ COMPONENT_ORIG_TARBALL_SIGNATURE = DBItem(10, """
454+ Component Orig Tarball Signature
455+
456+ This file is a detached signature for an Ubuntu component "orig"
457+ file.""")
458+
459
460 class SourcePackageType(DBEnumeratedType):
461 """Source Package Format
462
463=== modified file 'lib/lp/soyuz/model/files.py'
464--- lib/lp/soyuz/model/files.py 2015-07-08 16:05:11 +0000
465+++ lib/lp/soyuz/model/files.py 2016-06-01 02:29:15 +0000
466@@ -1,4 +1,4 @@
467-# Copyright 2009-2013 Canonical Ltd. This software is licensed under the
468+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
469 # GNU Affero General Public License version 3 (see the file LICENSE).
470
471 __metaclass__ = type
472@@ -42,7 +42,9 @@
473 def is_orig(self):
474 return self.filetype in (
475 SourcePackageFileType.ORIG_TARBALL,
476- SourcePackageFileType.COMPONENT_ORIG_TARBALL
477+ SourcePackageFileType.COMPONENT_ORIG_TARBALL,
478+ SourcePackageFileType.ORIG_TARBALL_SIGNATURE,
479+ SourcePackageFileType.COMPONENT_ORIG_TARBALL_SIGNATURE,
480 )
481
482