Merge lp:~wgrant/launchpad/gpgkey-fks into lp:launchpad
- gpgkey-fks
- Merge into devel
Proposed by
William Grant
Status: | Merged |
---|---|
Merged at revision: | 17939 |
Proposed branch: | lp:~wgrant/launchpad/gpgkey-fks |
Merge into: | lp:launchpad |
Prerequisite: | lp:~wgrant/launchpad/gpgkey-fks-db |
Diff against target: |
464 lines (+199/-15) 11 files modified
database/schema/security.cfg (+4/-1) lib/lp/archivepublisher/archivesigningkey.py (+8/-2) lib/lp/registry/model/codeofconduct.py (+6/-2) lib/lp/registry/model/distroseries.py (+10/-3) lib/lp/scripts/garbo.py (+78/-0) lib/lp/scripts/tests/test_garbo.py (+66/-1) lib/lp/soyuz/configure.zcml (+6/-1) lib/lp/soyuz/model/archive.py (+12/-5) lib/lp/soyuz/model/queue.py (+3/-0) lib/lp/soyuz/model/sourcepackagerelease.py (+4/-0) lib/lp/soyuz/scripts/gina/handlers.py (+2/-0) |
To merge this branch: | bzr merge lp:~wgrant/launchpad/gpgkey-fks |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email: mp+287710@code.launchpad.net |
Commit message
Set GPGKey FK replacement columns and add garbo jobs to backfill.
Description of the change
Set GPGKey FK replacement columns and add garbo jobs to backfill.
Using a Storm validator would be lovely, but construction gets angry when an incomplete object is flushed.
To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'database/schema/security.cfg' |
2 | --- database/schema/security.cfg 2016-03-02 21:21:26 +0000 |
3 | +++ database/schema/security.cfg 2016-03-03 18:43:25 +0000 |
4 | @@ -2277,6 +2277,7 @@ |
5 | public.accesspolicygrant = SELECT, DELETE |
6 | public.account = SELECT, DELETE |
7 | public.answercontact = SELECT, DELETE |
8 | +public.archive = SELECT, UPDATE |
9 | public.branch = SELECT, UPDATE |
10 | public.branchjob = SELECT, DELETE |
11 | public.binarypackagename = SELECT |
12 | @@ -2318,6 +2319,7 @@ |
13 | public.milestonetag = SELECT |
14 | public.openidconsumerassociation = SELECT, DELETE |
15 | public.openidconsumernonce = SELECT, DELETE |
16 | +public.packageupload = SELECT, UPDATE |
17 | public.person = SELECT, DELETE |
18 | public.personsettings = SELECT, UPDATE |
19 | public.product = SELECT, UPDATE |
20 | @@ -2327,9 +2329,10 @@ |
21 | public.previewdiff = SELECT, DELETE |
22 | public.revisionauthor = SELECT, UPDATE |
23 | public.revisioncache = SELECT, DELETE |
24 | +public.signedcodeofconduct = SELECT, UPDATE |
25 | public.snapfile = SELECT, DELETE |
26 | public.sourcepackagename = SELECT |
27 | -public.sourcepackagerelease = SELECT |
28 | +public.sourcepackagerelease = SELECT, UPDATE |
29 | public.sourcepackagepublishinghistory = SELECT, UPDATE |
30 | public.suggestivepotemplate = INSERT, DELETE |
31 | public.teammembership = SELECT, DELETE |
32 | |
33 | === modified file 'lib/lp/archivepublisher/archivesigningkey.py' |
34 | --- lib/lp/archivepublisher/archivesigningkey.py 2015-09-13 18:30:51 +0000 |
35 | +++ lib/lp/archivepublisher/archivesigningkey.py 2016-03-03 18:43:25 +0000 |
36 | @@ -70,7 +70,10 @@ |
37 | if self.archive != default_ppa: |
38 | if default_ppa.signing_key is None: |
39 | IArchiveSigningKey(default_ppa).generateSigningKey() |
40 | - self.archive.signing_key = default_ppa.signing_key |
41 | + key = default_ppa.signing_key |
42 | + self.archive.signing_key = key |
43 | + self.archive.signing_key_owner = key.owner |
44 | + self.archive._signing_key_fingerprint = key.fingerprint |
45 | return |
46 | |
47 | key_displayname = ( |
48 | @@ -105,9 +108,12 @@ |
49 | |
50 | algorithm = GPGKeyAlgorithm.items[pub_key.algorithm] |
51 | key_owner = getUtility(ILaunchpadCelebrities).ppa_key_guard |
52 | - self.archive.signing_key = getUtility(IGPGKeySet).new( |
53 | + key = getUtility(IGPGKeySet).new( |
54 | key_owner, pub_key.keyid, pub_key.fingerprint, pub_key.keysize, |
55 | algorithm, active=True, can_encrypt=pub_key.can_encrypt) |
56 | + self.archive.signing_key = key |
57 | + self.archive.signing_key_owner = key.owner |
58 | + self.archive._signing_key_fingerprint = key.fingerprint |
59 | |
60 | def signRepository(self, suite): |
61 | """See `IArchiveSigningKey`.""" |
62 | |
63 | === modified file 'lib/lp/registry/model/codeofconduct.py' |
64 | --- lib/lp/registry/model/codeofconduct.py 2015-07-10 15:31:28 +0000 |
65 | +++ lib/lp/registry/model/codeofconduct.py 2016-03-03 18:43:25 +0000 |
66 | @@ -19,6 +19,7 @@ |
67 | ForeignKey, |
68 | StringCol, |
69 | ) |
70 | +from storm.properties import Unicode |
71 | from zope.component import getUtility |
72 | from zope.interface import implementer |
73 | |
74 | @@ -181,6 +182,7 @@ |
75 | |
76 | signingkey = ForeignKey(foreignKey="GPGKey", dbName="signingkey", |
77 | notNull=False, default=None) |
78 | + signing_key_fingerprint = Unicode() |
79 | |
80 | datecreated = UtcDateTimeCol(dbName='datecreated', notNull=True, |
81 | default=UTC_NOW) |
82 | @@ -305,8 +307,10 @@ |
83 | 'space differences are acceptable).') |
84 | |
85 | # Store the signature |
86 | - signed = SignedCodeOfConduct(owner=user, signingkey=gpg, |
87 | - signedcode=signedcode, active=True) |
88 | + signed = SignedCodeOfConduct( |
89 | + owner=user, signingkey=gpg, |
90 | + signing_key_fingerprint=gpg.fingerprint if gpg else None, |
91 | + signedcode=signedcode, active=True) |
92 | |
93 | # Send Advertisement Email |
94 | subject = 'Your Code of Conduct signature has been acknowledged' |
95 | |
96 | === modified file 'lib/lp/registry/model/distroseries.py' |
97 | --- lib/lp/registry/model/distroseries.py 2016-02-05 20:28:29 +0000 |
98 | +++ lib/lp/registry/model/distroseries.py 2016-03-03 18:43:25 +0000 |
99 | @@ -1164,8 +1164,11 @@ |
100 | architecturehintlist=architecturehintlist, component=component, |
101 | creator=creator, urgency=urgency, changelog=changelog, |
102 | changelog_entry=changelog_entry, dsc=dsc, |
103 | - dscsigningkey=dscsigningkey, section=section, copyright=copyright, |
104 | - upload_archive=archive, |
105 | + dscsigningkey=dscsigningkey, |
106 | + signing_key_owner=dscsigningkey.owner if dscsigningkey else None, |
107 | + signing_key_fingerprint=( |
108 | + dscsigningkey.fingerprint if dscsigningkey else None), |
109 | + section=section, copyright=copyright, upload_archive=archive, |
110 | dsc_maintainer_rfc822=dsc_maintainer_rfc822, |
111 | dsc_standards_version=dsc_standards_version, |
112 | dsc_format=dsc_format, dsc_binaries=dsc_binaries, |
113 | @@ -1350,7 +1353,11 @@ |
114 | return PackageUpload( |
115 | distroseries=self, status=PackageUploadStatus.NEW, |
116 | pocket=pocket, archive=archive, changesfile=changes_file_alias, |
117 | - signing_key=signing_key, package_copy_job=package_copy_job) |
118 | + signing_key=signing_key, |
119 | + signing_key_owner=signing_key.owner if signing_key else None, |
120 | + signing_key_fingerprint=( |
121 | + signing_key.fingerprint if signing_key else None), |
122 | + package_copy_job=package_copy_job) |
123 | |
124 | def getPackageUploadQueue(self, state): |
125 | """See `IDistroSeries`.""" |
126 | |
127 | === modified file 'lib/lp/scripts/garbo.py' |
128 | --- lib/lp/scripts/garbo.py 2016-02-05 17:18:57 +0000 |
129 | +++ lib/lp/scripts/garbo.py 2016-03-03 18:43:25 +0000 |
130 | @@ -69,6 +69,7 @@ |
131 | RevisionCache, |
132 | ) |
133 | from lp.hardwaredb.model.hwdb import HWSubmission |
134 | +from lp.registry.model.codeofconduct import SignedCodeOfConduct |
135 | from lp.registry.model.commercialsubscription import CommercialSubscription |
136 | from lp.registry.model.person import ( |
137 | Person, |
138 | @@ -124,6 +125,7 @@ |
139 | from lp.soyuz.model.archive import Archive |
140 | from lp.soyuz.model.livefsbuild import LiveFSFile |
141 | from lp.soyuz.model.publishing import SourcePackagePublishingHistory |
142 | +from lp.soyuz.model.queue import PackageUpload |
143 | from lp.soyuz.model.reporting import LatestPersonSourcePackageReleaseCache |
144 | from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease |
145 | from lp.translations.interfaces.potemplate import IPOTemplateSet |
146 | @@ -1461,6 +1463,78 @@ |
147 | transaction.commit() |
148 | |
149 | |
150 | +class BaseKeyMigrator(TunableLoop): |
151 | + |
152 | + maximum_chunk_size = 5000 |
153 | + |
154 | + def __init__(self, log, abort_time=None): |
155 | + super(BaseKeyMigrator, self).__init__( |
156 | + log, abort_time) |
157 | + state = load_garbo_job_state(self.__class__.__name__) or {} |
158 | + self.start_at = state.get('next_id', 1) |
159 | + self.store = IMasterStore(self.klass) |
160 | + |
161 | + def findObjects(self): |
162 | + return self.store.find( |
163 | + self.klass, |
164 | + self.klass.id >= self.start_at).order_by( |
165 | + self.klass.id) |
166 | + |
167 | + def isDone(self): |
168 | + return ( |
169 | + not getFeatureFlag('gpg.migrator.%s' % self.klass.__name__) |
170 | + or self.findObjects().is_empty()) |
171 | + |
172 | + def __call__(self, chunk_size): |
173 | + objs = list(self.findObjects()[:chunk_size]) |
174 | + for obj in objs: |
175 | + key = getattr(obj, self.fk_attr, None) |
176 | + if self.fingerprint_attr: |
177 | + setattr( |
178 | + obj, self.fingerprint_attr, |
179 | + key.fingerprint if key else None) |
180 | + if self.owner_attr: |
181 | + setattr( |
182 | + obj, self.owner_attr, |
183 | + key.owner if key else None) |
184 | + self.start_at = objs[-1].id + 1 |
185 | + save_garbo_job_state( |
186 | + self.__class__.__name__, {'next_id': self.start_at}) |
187 | + transaction.commit() |
188 | + |
189 | + |
190 | +class ArchiveKeyMigrator(BaseKeyMigrator): |
191 | + |
192 | + klass = Archive |
193 | + fk_attr = 'signing_key' |
194 | + fingerprint_attr = '_signing_key_fingerprint' |
195 | + owner_attr = 'signing_key_owner' |
196 | + |
197 | + |
198 | +class PackageUploadKeyMigrator(BaseKeyMigrator): |
199 | + |
200 | + klass = PackageUpload |
201 | + fk_attr = 'signing_key' |
202 | + fingerprint_attr = 'signing_key_fingerprint' |
203 | + owner_attr = 'signing_key_owner' |
204 | + |
205 | + |
206 | +class SignedCodeOfConductKeyMigrator(BaseKeyMigrator): |
207 | + |
208 | + klass = SignedCodeOfConduct |
209 | + fk_attr = 'signingkey' |
210 | + fingerprint_attr = 'signing_key_fingerprint' |
211 | + owner_attr = None |
212 | + |
213 | + |
214 | +class SourcePackageReleaseKeyMigrator(BaseKeyMigrator): |
215 | + |
216 | + klass = SourcePackageRelease |
217 | + fk_attr = 'dscsigningkey' |
218 | + fingerprint_attr = 'signing_key_fingerprint' |
219 | + owner_attr = 'signing_key_owner' |
220 | + |
221 | + |
222 | class BaseDatabaseGarbageCollector(LaunchpadCronScript): |
223 | """Abstract base class to run a collection of TunableLoops.""" |
224 | script_name = None # Script name for locking and database user. Override. |
225 | @@ -1709,10 +1783,14 @@ |
226 | """ |
227 | script_name = 'garbo-hourly' |
228 | tunable_loops = [ |
229 | + ArchiveKeyMigrator, |
230 | BugHeatUpdater, |
231 | BugWatchScheduler, |
232 | DuplicateSessionPruner, |
233 | + PackageUploadKeyMigrator, |
234 | RevisionCachePruner, |
235 | + SignedCodeOfConductKeyMigrator, |
236 | + SourcePackageReleaseKeyMigrator, |
237 | UnusedSessionPruner, |
238 | ] |
239 | experimental_tunable_loops = [] |
240 | |
241 | === modified file 'lib/lp/scripts/tests/test_garbo.py' |
242 | --- lib/lp/scripts/tests/test_garbo.py 2016-02-06 02:55:51 +0000 |
243 | +++ lib/lp/scripts/tests/test_garbo.py 2016-03-03 18:43:25 +0000 |
244 | @@ -73,6 +73,7 @@ |
245 | from lp.registry.interfaces.accesspolicy import IAccessPolicySource |
246 | from lp.registry.interfaces.person import IPersonSet |
247 | from lp.registry.interfaces.teammembership import TeamMembershipStatus |
248 | +from lp.registry.model.codeofconduct import SignedCodeOfConduct |
249 | from lp.registry.model.commercialsubscription import CommercialSubscription |
250 | from lp.registry.model.person import PersonSettings |
251 | from lp.registry.model.teammembership import TeamMembership |
252 | @@ -128,7 +129,10 @@ |
253 | TestCase, |
254 | TestCaseWithFactory, |
255 | ) |
256 | -from lp.testing.dbuser import switch_dbuser |
257 | +from lp.testing.dbuser import ( |
258 | + dbuser, |
259 | + switch_dbuser, |
260 | + ) |
261 | from lp.testing.layers import ( |
262 | DatabaseLayer, |
263 | LaunchpadScriptLayer, |
264 | @@ -1390,6 +1394,67 @@ |
265 | self._test_LiveFSFilePruner( |
266 | 'application/octet-stream', 0, expected_count=1) |
267 | |
268 | + def test_ArchiveKeyMigrator(self): |
269 | + with dbuser('testadmin'): |
270 | + key = self.factory.makeGPGKey(self.factory.makePerson()) |
271 | + a1 = self.factory.makeArchive() |
272 | + a2 = self.factory.makeArchive() |
273 | + removeSecurityProxy(a2).signing_key = key |
274 | + self.assertIs(None, a1._signing_key_fingerprint) |
275 | + self.assertIs(None, a1.signing_key_owner) |
276 | + self.assertIs(None, a2._signing_key_fingerprint) |
277 | + self.assertIs(None, a2.signing_key_owner) |
278 | + with FeatureFixture({'gpg.migrator.Archive': 'on'}): |
279 | + self.runHourly() |
280 | + self.assertIs(None, a1._signing_key_fingerprint) |
281 | + self.assertIs(None, a1.signing_key_owner) |
282 | + self.assertEqual(key.fingerprint, a2._signing_key_fingerprint) |
283 | + self.assertEqual(key.owner, a2.signing_key_owner) |
284 | + |
285 | + def test_PackageUploadKeyMigrator(self): |
286 | + with dbuser('testadmin'): |
287 | + key = self.factory.makeGPGKey(self.factory.makePerson()) |
288 | + pu1 = self.factory.makePackageUpload() |
289 | + pu2 = self.factory.makePackageUpload(signing_key=key) |
290 | + npu2 = removeSecurityProxy(pu2) |
291 | + npu2.signing_key_fingerprint = npu2.signing_key_owner = None |
292 | + self.assertIs(None, pu1.signing_key_fingerprint) |
293 | + self.assertIs(None, pu1.signing_key_owner) |
294 | + self.assertIs(None, pu2.signing_key_fingerprint) |
295 | + self.assertIs(None, pu2.signing_key_owner) |
296 | + with FeatureFixture({'gpg.migrator.PackageUpload': 'on'}): |
297 | + self.runHourly() |
298 | + self.assertIs(None, pu1.signing_key_fingerprint) |
299 | + self.assertIs(None, pu1.signing_key_owner) |
300 | + self.assertEqual(key.fingerprint, pu2.signing_key_fingerprint) |
301 | + self.assertEqual(key.owner, pu2.signing_key_owner) |
302 | + |
303 | + def test_SignedCodeOfConductKeyMigrator(self): |
304 | + coc = SignedCodeOfConduct.get(1) |
305 | + self.assertIs(None, coc.signing_key_fingerprint) |
306 | + with FeatureFixture({'gpg.migrator.SignedCodeOfConduct': 'on'}): |
307 | + self.runHourly() |
308 | + self.assertEqual( |
309 | + 'ABCDEF0123456789ABCDDCBA0000111112345678', |
310 | + coc.signing_key_fingerprint) |
311 | + |
312 | + def test_SourcePackageReleaseKeyMigrator(self): |
313 | + with dbuser('testadmin'): |
314 | + key = self.factory.makeGPGKey(self.factory.makePerson()) |
315 | + spr1 = self.factory.makeSourcePackageRelease() |
316 | + spr2 = self.factory.makeSourcePackageRelease() |
317 | + removeSecurityProxy(spr2).dscsigningkey = key |
318 | + self.assertIs(None, spr1.signing_key_fingerprint) |
319 | + self.assertIs(None, spr1.signing_key_owner) |
320 | + self.assertIs(None, spr2.signing_key_fingerprint) |
321 | + self.assertIs(None, spr2.signing_key_owner) |
322 | + with FeatureFixture({'gpg.migrator.SourcePackageRelease': 'on'}): |
323 | + self.runHourly() |
324 | + self.assertIs(None, spr1.signing_key_fingerprint) |
325 | + self.assertIs(None, spr1.signing_key_owner) |
326 | + self.assertEqual(key.fingerprint, spr2.signing_key_fingerprint) |
327 | + self.assertEqual(key.owner, spr2.signing_key_owner) |
328 | + |
329 | def test_PersonSettingsENFPopulator(self): |
330 | switch_dbuser('testadmin') |
331 | store = IMasterStore(PersonSettings) |
332 | |
333 | === modified file 'lib/lp/soyuz/configure.zcml' |
334 | --- lib/lp/soyuz/configure.zcml 2016-01-08 14:35:52 +0000 |
335 | +++ lib/lp/soyuz/configure.zcml 2016-03-03 18:43:25 +0000 |
336 | @@ -75,6 +75,7 @@ |
337 | class="lp.soyuz.model.sourcepackagerelease.SourcePackageRelease"> |
338 | <allow |
339 | interface="lp.soyuz.interfaces.sourcepackagerelease.ISourcePackageRelease"/> |
340 | + <allow attributes="signing_key_fingerprint signing_key_owner" /> |
341 | <!-- changelog needs to be updated when unembargoing --> |
342 | <require |
343 | permission="launchpad.Edit" |
344 | @@ -143,6 +144,8 @@ |
345 | changesfile |
346 | changes_file_url |
347 | signing_key |
348 | + signing_key_fingerprint |
349 | + signing_key_owner |
350 | archive |
351 | sources |
352 | sourceFileUrls |
353 | @@ -386,7 +389,9 @@ |
354 | set_schema="lp.soyuz.interfaces.archive.IArchiveRestricted"/> |
355 | <require |
356 | permission="launchpad.InternalScriptsOnly" |
357 | - set_attributes="distribution signing_key"/> |
358 | + attributes="signing_key_owner _signing_key_fingerprint" |
359 | + set_attributes="distribution signing_key signing_key_owner |
360 | + _signing_key_fingerprint"/> |
361 | </class> |
362 | <adapter |
363 | for="lp.soyuz.interfaces.archive.IArchive" |
364 | |
365 | === modified file 'lib/lp/soyuz/model/archive.py' |
366 | --- lib/lp/soyuz/model/archive.py 2015-11-26 15:46:38 +0000 |
367 | +++ lib/lp/soyuz/model/archive.py 2016-03-03 18:43:25 +0000 |
368 | @@ -23,21 +23,22 @@ |
369 | IntCol, |
370 | StringCol, |
371 | ) |
372 | +from storm.base import Storm |
373 | from storm.expr import ( |
374 | And, |
375 | + Count, |
376 | Desc, |
377 | + Join, |
378 | Not, |
379 | Or, |
380 | Select, |
381 | Sum, |
382 | ) |
383 | -from storm.locals import ( |
384 | - Count, |
385 | +from storm.properties import ( |
386 | Int, |
387 | - Join, |
388 | - Reference, |
389 | - Storm, |
390 | + Unicode, |
391 | ) |
392 | +from storm.references import Reference |
393 | from storm.store import Store |
394 | from zope.component import ( |
395 | getAdapter, |
396 | @@ -339,6 +340,9 @@ |
397 | |
398 | signing_key = ForeignKey( |
399 | foreignKey='GPGKey', dbName='signing_key', notNull=False) |
400 | + signing_key_owner_id = Int(name="signing_key_owner") |
401 | + signing_key_owner = Reference(signing_key_owner_id, 'Person.id') |
402 | + _signing_key_fingerprint = Unicode(name="signing_key_fingerprint") |
403 | |
404 | relative_build_score = IntCol( |
405 | dbName='relative_build_score', notNull=True, default=0) |
406 | @@ -2534,6 +2538,9 @@ |
407 | owner=owner, distribution=distribution, name=name, |
408 | displayname=displayname, description=description, |
409 | purpose=purpose, publish=publish, signing_key=signing_key, |
410 | + signing_key_owner=signing_key.owner if signing_key else None, |
411 | + _signing_key_fingerprint=( |
412 | + signing_key.fingerprint if signing_key else None), |
413 | require_virtualized=require_virtualized) |
414 | |
415 | # Upon creation archives are enabled by default. |
416 | |
417 | === modified file 'lib/lp/soyuz/model/queue.py' |
418 | --- lib/lp/soyuz/model/queue.py 2016-02-05 16:51:12 +0000 |
419 | +++ lib/lp/soyuz/model/queue.py 2016-03-03 18:43:25 +0000 |
420 | @@ -186,6 +186,9 @@ |
421 | |
422 | signing_key = ForeignKey( |
423 | foreignKey='GPGKey', dbName='signing_key', notNull=False) |
424 | + signing_key_owner_id = Int(name="signing_key_owner") |
425 | + signing_key_owner = Reference(signing_key_owner_id, 'Person.id') |
426 | + signing_key_fingerprint = Unicode() |
427 | |
428 | package_copy_job_id = Int(name='package_copy_job', allow_none=True) |
429 | package_copy_job = Reference(package_copy_job_id, 'PackageCopyJob.id') |
430 | |
431 | === modified file 'lib/lp/soyuz/model/sourcepackagerelease.py' |
432 | --- lib/lp/soyuz/model/sourcepackagerelease.py 2016-02-05 15:16:29 +0000 |
433 | +++ lib/lp/soyuz/model/sourcepackagerelease.py 2016-03-03 18:43:25 +0000 |
434 | @@ -30,6 +30,7 @@ |
435 | Desc, |
436 | Int, |
437 | Reference, |
438 | + Unicode, |
439 | ) |
440 | from storm.store import Store |
441 | from zope.component import getUtility |
442 | @@ -89,6 +90,9 @@ |
443 | dbName='maintainer', foreignKey='Person', |
444 | storm_validator=validate_public_person, notNull=True) |
445 | dscsigningkey = ForeignKey(foreignKey='GPGKey', dbName='dscsigningkey') |
446 | + signing_key_owner_id = Int(name="signing_key_owner") |
447 | + signing_key_owner = Reference(signing_key_owner_id, 'Person.id') |
448 | + signing_key_fingerprint = Unicode() |
449 | urgency = EnumCol(dbName='urgency', schema=SourcePackageUrgency, |
450 | default=SourcePackageUrgency.LOW, notNull=True) |
451 | dateuploaded = UtcDateTimeCol(dbName='dateuploaded', notNull=True, |
452 | |
453 | === modified file 'lib/lp/soyuz/scripts/gina/handlers.py' |
454 | --- lib/lp/soyuz/scripts/gina/handlers.py 2015-05-20 11:31:11 +0000 |
455 | +++ lib/lp/soyuz/scripts/gina/handlers.py 2016-03-03 18:43:25 +0000 |
456 | @@ -616,6 +616,8 @@ |
457 | sourcepackagename=name.id, |
458 | maintainer=maintainer.id, |
459 | dscsigningkey=key, |
460 | + signing_key_owner=key.owner if key else None, |
461 | + signing_key_fingerprint=key.fingerprint if key else None, |
462 | urgency=ChangesFile.urgency_map[src.urgency], |
463 | dateuploaded=src.date_uploaded, |
464 | dsc=src.dsc, |