Merge lp:~apw/launchpad/signing-reinstate-raw-uefi-custom-upload into lp:launchpad
- signing-reinstate-raw-uefi-custom-upload
- Merge into devel
Proposed by
Andy Whitcroft
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 18080 | ||||
Proposed branch: | lp:~apw/launchpad/signing-reinstate-raw-uefi-custom-upload | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
415 lines (+165/-46) 9 files modified
lib/lp/archivepublisher/configure.zcml (+7/-0) lib/lp/archivepublisher/signing.py (+22/-2) lib/lp/archivepublisher/tests/test_signing.py (+66/-32) lib/lp/archiveuploader/nascentuploadfile.py (+8/-3) lib/lp/soyuz/browser/queue.py (+1/-0) lib/lp/soyuz/enums.py (+7/-1) lib/lp/soyuz/model/queue.py (+5/-2) lib/lp/soyuz/scripts/custom_uploads_copier.py (+7/-2) lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py (+42/-4) |
||||
To merge this branch: | bzr merge lp:~apw/launchpad/signing-reinstate-raw-uefi-custom-upload | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email: mp+295848@code.launchpad.net |
Commit message
Reinstate the raw-uefi custom upload as a distinct type.
Description of the change
Reinstate the raw-uefi custom upload as a distinct type. This utilises the same machinery as raw-signing. The only difference is the location in dists, with raw-uefi landing in dists/*/uefi and raw-signing landing in dists/*/signing.
To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Approve
Revision history for this message
Andy Whitcroft (apw) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/archivepublisher/configure.zcml' |
2 | --- lib/lp/archivepublisher/configure.zcml 2016-05-23 10:46:55 +0000 |
3 | +++ lib/lp/archivepublisher/configure.zcml 2016-05-31 12:46:39 +0000 |
4 | @@ -88,6 +88,13 @@ |
5 | interface="lp.soyuz.interfaces.queue.ICustomUploadHandler"/> |
6 | </securedutility> |
7 | <securedutility |
8 | + class="lp.archivepublisher.signing.UefiUpload" |
9 | + provides="lp.soyuz.interfaces.queue.ICustomUploadHandler" |
10 | + name="UEFI"> |
11 | + <allow |
12 | + interface="lp.soyuz.interfaces.queue.ICustomUploadHandler"/> |
13 | + </securedutility> |
14 | + <securedutility |
15 | class="lp.archivepublisher.signing.SigningUpload" |
16 | provides="lp.soyuz.interfaces.queue.ICustomUploadHandler" |
17 | name="SIGNING"> |
18 | |
19 | === modified file 'lib/lp/archivepublisher/signing.py' |
20 | --- lib/lp/archivepublisher/signing.py 2016-05-26 10:46:04 +0000 |
21 | +++ lib/lp/archivepublisher/signing.py 2016-05-31 12:46:39 +0000 |
22 | @@ -15,6 +15,7 @@ |
23 | |
24 | __all__ = [ |
25 | "SigningUpload", |
26 | + "UefiUpload", |
27 | ] |
28 | |
29 | import os |
30 | @@ -63,6 +64,8 @@ |
31 | """ |
32 | custom_type = "signing" |
33 | |
34 | + dists_directory = "signed" |
35 | + |
36 | @staticmethod |
37 | def parsePath(tarfile_path): |
38 | tarfile_base = os.path.basename(tarfile_path) |
39 | @@ -94,8 +97,8 @@ |
40 | |
41 | self.setComponents(tarfile_path) |
42 | |
43 | - dists_signed = os.path.join( |
44 | - pubconf.archiveroot, "dists", suite, "main", "signed") |
45 | + dists_signed = os.path.join(pubconf.archiveroot, "dists", |
46 | + suite, "main", self.dists_directory) |
47 | self.targetdir = os.path.join( |
48 | dists_signed, "%s-%s" % (self.package, self.arch)) |
49 | self.archiveroot = pubconf.archiveroot |
50 | @@ -302,3 +305,20 @@ |
51 | |
52 | def shouldInstall(self, filename): |
53 | return filename.startswith("%s/" % self.version) |
54 | + |
55 | + |
56 | +class UefiUpload(SigningUpload): |
57 | + """Legacy UEFI Signing custom upload. |
58 | + |
59 | + Provides backwards compatibility UEFI signing uploads. Existing |
60 | + packages use the raw-uefi custom upload and expect the results |
61 | + to be published to dists/*/uefi. These are a functional subset of |
62 | + raw-signing custom uploads differing only in where they are published |
63 | + in the archive. |
64 | + |
65 | + We expect to be able to remove this upload type once all existing |
66 | + packages are converted to the new form and location. |
67 | + """ |
68 | + custom_type = "uefi" |
69 | + |
70 | + dists_directory = "uefi" |
71 | |
72 | === modified file 'lib/lp/archivepublisher/tests/test_signing.py' |
73 | --- lib/lp/archivepublisher/tests/test_signing.py 2016-05-26 10:46:39 +0000 |
74 | +++ lib/lp/archivepublisher/tests/test_signing.py 2016-05-31 12:46:39 +0000 |
75 | @@ -15,7 +15,10 @@ |
76 | CustomUploadAlreadyExists, |
77 | CustomUploadBadUmask, |
78 | ) |
79 | -from lp.archivepublisher.signing import SigningUpload |
80 | +from lp.archivepublisher.signing import ( |
81 | + SigningUpload, |
82 | + UefiUpload, |
83 | + ) |
84 | from lp.services.osutils import write_file |
85 | from lp.services.tarfile_helpers import LaunchpadWriteTarFile |
86 | from lp.testing import TestCase |
87 | @@ -98,10 +101,10 @@ |
88 | self.signingautokey = True |
89 | |
90 | |
91 | -class TestSigning(TestCase): |
92 | +class TestSigningHelpers(TestCase): |
93 | |
94 | def setUp(self): |
95 | - super(TestSigning, self).setUp() |
96 | + super(TestSigningHelpers, self).setUp() |
97 | self.temp_dir = self.makeTemporaryDirectory() |
98 | self.signing_dir = self.makeTemporaryDirectory() |
99 | self.pubconf = FakeConfigPrimary(self.temp_dir, self.signing_dir) |
100 | @@ -135,43 +138,42 @@ |
101 | self.buffer = open(self.path, "wb") |
102 | self.archive = LaunchpadWriteTarFile(self.buffer) |
103 | |
104 | - def process_emulate(self): |
105 | - self.archive.close() |
106 | - self.buffer.close() |
107 | - upload = SigningUpload() |
108 | - # Under no circumstances is it safe to execute actual commands. |
109 | - self.fake_call = FakeMethod(result=0) |
110 | - upload.callLog = FakeMethodCallLog(upload=upload) |
111 | - self.useFixture(MonkeyPatch("subprocess.call", self.fake_call)) |
112 | - upload.process(self.pubconf, self.path, self.suite) |
113 | - |
114 | - return upload |
115 | - |
116 | - def process(self): |
117 | - self.archive.close() |
118 | - self.buffer.close() |
119 | - upload = SigningUpload() |
120 | - upload.signUefi = FakeMethod() |
121 | - upload.signKmod = FakeMethod() |
122 | - # Under no circumstances is it safe to execute actual commands. |
123 | - fake_call = FakeMethod(result=0) |
124 | - self.useFixture(MonkeyPatch("subprocess.call", fake_call)) |
125 | - upload.process(self.pubconf, self.path, self.suite) |
126 | - self.assertEqual(0, fake_call.call_count) |
127 | - |
128 | - return upload |
129 | - |
130 | def getDistsPath(self): |
131 | return os.path.join(self.pubconf.archiveroot, "dists", |
132 | self.suite, "main") |
133 | |
134 | + |
135 | +class TestSigning(TestSigningHelpers): |
136 | + |
137 | def getSignedPath(self, loader_type, arch): |
138 | return os.path.join(self.getDistsPath(), "signed", |
139 | "%s-%s" % (loader_type, arch)) |
140 | |
141 | - def getUefiPath(self, loader_type, arch): |
142 | - return os.path.join(self.getDistsPath(), "uefi", |
143 | - "%s-%s" % (loader_type, arch)) |
144 | + def process_emulate(self): |
145 | + self.archive.close() |
146 | + self.buffer.close() |
147 | + upload = SigningUpload() |
148 | + # Under no circumstances is it safe to execute actual commands. |
149 | + self.fake_call = FakeMethod(result=0) |
150 | + upload.callLog = FakeMethodCallLog(upload=upload) |
151 | + self.useFixture(MonkeyPatch("subprocess.call", self.fake_call)) |
152 | + upload.process(self.pubconf, self.path, self.suite) |
153 | + |
154 | + return upload |
155 | + |
156 | + def process(self): |
157 | + self.archive.close() |
158 | + self.buffer.close() |
159 | + upload = SigningUpload() |
160 | + upload.signUefi = FakeMethod() |
161 | + upload.signKmod = FakeMethod() |
162 | + # Under no circumstances is it safe to execute actual commands. |
163 | + fake_call = FakeMethod(result=0) |
164 | + self.useFixture(MonkeyPatch("subprocess.call", fake_call)) |
165 | + upload.process(self.pubconf, self.path, self.suite) |
166 | + self.assertEqual(0, fake_call.call_count) |
167 | + |
168 | + return upload |
169 | |
170 | def test_archive_copy(self): |
171 | # If there is no key/cert configuration, processing succeeds but |
172 | @@ -599,3 +601,35 @@ |
173 | self.assertTrue(os.path.exists(self.kmod_x509)) |
174 | self.assertEqual(stat.S_IMODE(os.stat(self.kmod_pem).st_mode), 0o600) |
175 | self.assertEqual(stat.S_IMODE(os.stat(self.kmod_x509).st_mode), 0o644) |
176 | + |
177 | + |
178 | +class TestUefi(TestSigningHelpers): |
179 | + |
180 | + def getSignedPath(self, loader_type, arch): |
181 | + return os.path.join(self.getDistsPath(), "uefi", |
182 | + "%s-%s" % (loader_type, arch)) |
183 | + |
184 | + def process(self): |
185 | + self.archive.close() |
186 | + self.buffer.close() |
187 | + upload = UefiUpload() |
188 | + upload.signUefi = FakeMethod() |
189 | + upload.signKmod = FakeMethod() |
190 | + # Under no circumstances is it safe to execute actual commands. |
191 | + fake_call = FakeMethod(result=0) |
192 | + self.useFixture(MonkeyPatch("subprocess.call", fake_call)) |
193 | + upload.process(self.pubconf, self.path, self.suite) |
194 | + self.assertEqual(0, fake_call.call_count) |
195 | + |
196 | + return upload |
197 | + |
198 | + def test_installed(self): |
199 | + # Files in the tarball are installed correctly. |
200 | + self.setUpUefiKeys() |
201 | + self.openArchive("test", "1.0", "amd64") |
202 | + self.archive.add_file("1.0/empty.efi", "") |
203 | + self.process() |
204 | + self.assertTrue(os.path.isdir(os.path.join( |
205 | + self.getDistsPath(), "uefi"))) |
206 | + self.assertTrue(os.path.exists(os.path.join( |
207 | + self.getSignedPath("test", "amd64"), "1.0", "empty.efi"))) |
208 | |
209 | === modified file 'lib/lp/archiveuploader/nascentuploadfile.py' |
210 | --- lib/lp/archiveuploader/nascentuploadfile.py 2016-05-06 09:16:30 +0000 |
211 | +++ lib/lp/archiveuploader/nascentuploadfile.py 2016-05-31 12:46:39 +0000 |
212 | @@ -33,7 +33,10 @@ |
213 | from lp.archivepublisher.debian_installer import DebianInstallerUpload |
214 | from lp.archivepublisher.dist_upgrader import DistUpgraderUpload |
215 | from lp.archivepublisher.rosetta_translations import RosettaTranslationsUpload |
216 | -from lp.archivepublisher.signing import SigningUpload |
217 | +from lp.archivepublisher.signing import ( |
218 | + SigningUpload, |
219 | + UefiUpload, |
220 | + ) |
221 | from lp.archiveuploader.utils import ( |
222 | determine_source_file_type, |
223 | prefix_multi_line_string, |
224 | @@ -258,8 +261,8 @@ |
225 | PackageUploadCustomFormat.STATIC_TRANSLATIONS, |
226 | 'raw-meta-data': |
227 | PackageUploadCustomFormat.META_DATA, |
228 | + 'raw-uefi': PackageUploadCustomFormat.UEFI, |
229 | 'raw-signing': PackageUploadCustomFormat.SIGNING, |
230 | - 'raw-uefi': PackageUploadCustomFormat.SIGNING, # Compatibility |
231 | } |
232 | |
233 | custom_handlers = { |
234 | @@ -268,6 +271,7 @@ |
235 | PackageUploadCustomFormat.DDTP_TARBALL: DdtpTarballUpload, |
236 | PackageUploadCustomFormat.ROSETTA_TRANSLATIONS: |
237 | RosettaTranslationsUpload, |
238 | + PackageUploadCustomFormat.UEFI: UefiUpload, |
239 | PackageUploadCustomFormat.SIGNING: SigningUpload, |
240 | } |
241 | |
242 | @@ -309,7 +313,8 @@ |
243 | """Return whether this custom upload can be automatically approved.""" |
244 | # Signing uploads will be signed, and must therefore be approved |
245 | # by a human. |
246 | - if self.custom_type == PackageUploadCustomFormat.SIGNING: |
247 | + if self.custom_type in (PackageUploadCustomFormat.UEFI, |
248 | + PackageUploadCustomFormat.SIGNING): |
249 | return False |
250 | return True |
251 | |
252 | |
253 | === modified file 'lib/lp/soyuz/browser/queue.py' |
254 | --- lib/lp/soyuz/browser/queue.py 2016-05-09 18:07:49 +0000 |
255 | +++ lib/lp/soyuz/browser/queue.py 2016-05-31 12:46:39 +0000 |
256 | @@ -574,6 +574,7 @@ |
257 | (self.contains_installer, ("Installer", 'ubuntu-icon')), |
258 | (self.contains_upgrader, ("Upgrader", 'ubuntu-icon')), |
259 | (self.contains_ddtp, (ddtp, 'ubuntu-icon')), |
260 | + (self.contains_uefi, ("UEFI Objects for Signing", 'ubuntu-icon')), |
261 | (self.contains_signing, ("Objects for Signing", 'ubuntu-icon')), |
262 | ] |
263 | return [ |
264 | |
265 | === modified file 'lib/lp/soyuz/enums.py' |
266 | --- lib/lp/soyuz/enums.py 2016-05-03 14:44:33 +0000 |
267 | +++ lib/lp/soyuz/enums.py 2016-05-31 12:46:39 +0000 |
268 | @@ -481,7 +481,13 @@ |
269 | the Software Center. |
270 | """) |
271 | |
272 | - SIGNING = DBItem(6, """ |
273 | + UEFI = DBItem(6, """ |
274 | + uefi |
275 | + |
276 | + A tarball containing EFI images to be signed. |
277 | + """) |
278 | + |
279 | + SIGNING = DBItem(7, """ |
280 | signing |
281 | |
282 | A tarball containing images to be signed. |
283 | |
284 | === modified file 'lib/lp/soyuz/model/queue.py' |
285 | --- lib/lp/soyuz/model/queue.py 2016-05-23 11:18:16 +0000 |
286 | +++ lib/lp/soyuz/model/queue.py 2016-05-31 12:46:39 +0000 |
287 | @@ -654,12 +654,15 @@ |
288 | return PackageUploadCustomFormat.DDTP_TARBALL in self._customFormats |
289 | |
290 | @cachedproperty |
291 | + def contains_uefi(self): |
292 | + """See `IPackageUpload`.""" |
293 | + return PackageUploadCustomFormat.UEFI in self._customFormats |
294 | + |
295 | + @cachedproperty |
296 | def contains_signing(self): |
297 | """See `IPackageUpload`.""" |
298 | return PackageUploadCustomFormat.SIGNING in self._customFormats |
299 | |
300 | - contains_uefi = contains_signing |
301 | - |
302 | @property |
303 | def package_name(self): |
304 | """See `IPackageUpload`.""" |
305 | |
306 | === modified file 'lib/lp/soyuz/scripts/custom_uploads_copier.py' |
307 | --- lib/lp/soyuz/scripts/custom_uploads_copier.py 2016-05-06 09:16:30 +0000 |
308 | +++ lib/lp/soyuz/scripts/custom_uploads_copier.py 2016-05-31 12:46:39 +0000 |
309 | @@ -18,7 +18,10 @@ |
310 | from lp.archivepublisher.debian_installer import DebianInstallerUpload |
311 | from lp.archivepublisher.dist_upgrader import DistUpgraderUpload |
312 | from lp.archivepublisher.rosetta_translations import RosettaTranslationsUpload |
313 | -from lp.archivepublisher.signing import SigningUpload |
314 | +from lp.archivepublisher.signing import ( |
315 | + SigningUpload, |
316 | + UefiUpload, |
317 | + ) |
318 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
319 | from lp.services.database.bulk import load_referencing |
320 | from lp.soyuz.enums import PackageUploadCustomFormat |
321 | @@ -40,6 +43,7 @@ |
322 | PackageUploadCustomFormat.DDTP_TARBALL: DdtpTarballUpload, |
323 | PackageUploadCustomFormat.ROSETTA_TRANSLATIONS: |
324 | RosettaTranslationsUpload, |
325 | + PackageUploadCustomFormat.UEFI: UefiUpload, |
326 | PackageUploadCustomFormat.SIGNING: SigningUpload, |
327 | } |
328 | |
329 | @@ -63,7 +67,8 @@ |
330 | return True |
331 | # Signing uploads will be signed, and must therefore be approved |
332 | # by a human. |
333 | - if custom.customformat == PackageUploadCustomFormat.SIGNING: |
334 | + if custom.customformat in (PackageUploadCustomFormat.UEFI, |
335 | + PackageUploadCustomFormat.SIGNING): |
336 | return False |
337 | return True |
338 | |
339 | |
340 | === modified file 'lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py' |
341 | --- lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2016-05-06 09:16:30 +0000 |
342 | +++ lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2016-05-31 12:46:39 +0000 |
343 | @@ -409,7 +409,7 @@ |
344 | self.assertEqual(PackageUploadStatus.ACCEPTED, copied_pu.status) |
345 | |
346 | def test_copyUpload_unapproves_signing_from_different_archive(self): |
347 | - # Copies of UEFI custom uploads to a primary archive are set to |
348 | + # Copies of signing custom uploads to a primary archive are set to |
349 | # UNAPPROVED, since they will normally end up being signed. |
350 | target_series = self.factory.makeDistroSeries() |
351 | archive = self.factory.makeArchive( |
352 | @@ -422,22 +422,60 @@ |
353 | self.assertEqual(PackageUploadStatus.UNAPPROVED, copied_pu.status) |
354 | |
355 | def test_copyUpload_approves_signing_from_same_archive(self): |
356 | + # Copies of signing custom uploads within the same archive are |
357 | + # automatically accepted, since they have already been signed. |
358 | + original_upload = self.makeUpload( |
359 | + custom_type=PackageUploadCustomFormat.SIGNING) |
360 | + target_series = self.factory.makeDistroSeries() |
361 | + copier = CustomUploadsCopier(target_series) |
362 | + copied_pu = copier.copyUpload(original_upload).packageupload |
363 | + self.assertEqual(PackageUploadStatus.ACCEPTED, copied_pu.status) |
364 | + |
365 | + def test_copyUpload_approves_signing_to_ppa(self): |
366 | + # Copies of signing custom uploads to a PPA are automatically accepted, |
367 | + # since PPAs have much more limited upload permissions than the main |
368 | + # archive, and in any case PPAs do not have an upload approval |
369 | + # workflow. |
370 | + original_upload = self.makeUpload( |
371 | + custom_type=PackageUploadCustomFormat.SIGNING) |
372 | + target_series = self.factory.makeDistroSeries() |
373 | + target_archive = self.factory.makeArchive( |
374 | + distribution=target_series.distribution) |
375 | + copier = CustomUploadsCopier( |
376 | + target_series, target_archive=target_archive) |
377 | + copied_pu = copier.copyUpload(original_upload).packageupload |
378 | + self.assertEqual(PackageUploadStatus.ACCEPTED, copied_pu.status) |
379 | + |
380 | + def test_copyUpload_unapproves_uefi_from_different_archive(self): |
381 | + # Copies of UEFI custom uploads to a primary archive are set to |
382 | + # UNAPPROVED, since they will normally end up being signed. |
383 | + target_series = self.factory.makeDistroSeries() |
384 | + archive = self.factory.makeArchive( |
385 | + distribution=target_series.distribution) |
386 | + original_upload = self.makeUpload( |
387 | + archive=archive, custom_type=PackageUploadCustomFormat.UEFI) |
388 | + copier = CustomUploadsCopier( |
389 | + target_series, target_archive=target_series.main_archive) |
390 | + copied_pu = copier.copyUpload(original_upload).packageupload |
391 | + self.assertEqual(PackageUploadStatus.UNAPPROVED, copied_pu.status) |
392 | + |
393 | + def test_copyUpload_approves_uefi_from_same_archive(self): |
394 | # Copies of UEFI custom uploads within the same archive are |
395 | # automatically accepted, since they have already been signed. |
396 | original_upload = self.makeUpload( |
397 | - custom_type=PackageUploadCustomFormat.SIGNING) |
398 | + custom_type=PackageUploadCustomFormat.UEFI) |
399 | target_series = self.factory.makeDistroSeries() |
400 | copier = CustomUploadsCopier(target_series) |
401 | copied_pu = copier.copyUpload(original_upload).packageupload |
402 | self.assertEqual(PackageUploadStatus.ACCEPTED, copied_pu.status) |
403 | |
404 | - def test_copyUpload_approves_signing_to_ppa(self): |
405 | + def test_copyUpload_approves_uefi_to_ppa(self): |
406 | # Copies of UEFI custom uploads to a PPA are automatically accepted, |
407 | # since PPAs have much more limited upload permissions than the main |
408 | # archive, and in any case PPAs do not have an upload approval |
409 | # workflow. |
410 | original_upload = self.makeUpload( |
411 | - custom_type=PackageUploadCustomFormat.SIGNING) |
412 | + custom_type=PackageUploadCustomFormat.UEFI) |
413 | target_series = self.factory.makeDistroSeries() |
414 | target_archive = self.factory.makeArchive( |
415 | distribution=target_series.distribution) |
Changes as requested pushed to the branch. Thanks for your reviews.