Merge ~cjwatson/launchpad:generate-copy-archive-signing-keys into launchpad:master
- Git
- lp:~cjwatson/launchpad
- generate-copy-archive-signing-keys
- Merge into master
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | ddb45f5bb1c2197a2f05ced4652577bb1c893def |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:generate-copy-archive-signing-keys |
Merge into: | launchpad:master |
Diff against target: |
322 lines (+103/-24) 6 files modified
lib/lp/archivepublisher/archivegpgsigningkey.py (+12/-3) lib/lp/archivepublisher/tests/archive-signing.txt (+35/-7) lib/lp/soyuz/interfaces/archive.py (+4/-2) lib/lp/soyuz/model/archive.py (+2/-2) lib/lp/soyuz/scripts/ppakeygenerator.py (+11/-5) lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py (+39/-5) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+413406@code.launchpad.net |
Commit message
Extend ppa-generate-keys to generate keys for copy archives too
Description of the change
It's currently awkward to run builds that use the output of test rebuilds, since they're only signed if we go through some manual steps to arrange that. Since the copy archive publisher has access to the signing service, having it generate signing keys is straightforward enough, so let's just do that.
This requires a separate invocation with the `--copy-archives` option (mainly since copy archives are published on a different machine so the signing keys need to be authorized for use by that machine).
Once we have this running automatically on production, we should change `Archive.
Ioana Lasc (ilasc) : | # |
Preview Diff
1 | diff --git a/lib/lp/archivepublisher/archivegpgsigningkey.py b/lib/lp/archivepublisher/archivegpgsigningkey.py | |||
2 | index c32bd9a..c1ada20 100644 | |||
3 | --- a/lib/lp/archivepublisher/archivegpgsigningkey.py | |||
4 | +++ b/lib/lp/archivepublisher/archivegpgsigningkey.py | |||
5 | @@ -251,7 +251,9 @@ class ArchiveGPGSigningKey(SignableArchive): | |||
6 | 251 | # Always generate signing keys for the default PPA, even if it | 251 | # Always generate signing keys for the default PPA, even if it |
7 | 252 | # was not specifically requested. The default PPA signing key | 252 | # was not specifically requested. The default PPA signing key |
8 | 253 | # is then propagated to the context named-ppa. | 253 | # is then propagated to the context named-ppa. |
10 | 254 | default_ppa = self.archive.owner.archive | 254 | default_ppa = ( |
11 | 255 | self.archive.owner.archive if self.archive.is_ppa | ||
12 | 256 | else self.archive) | ||
13 | 255 | if self.archive != default_ppa: | 257 | if self.archive != default_ppa: |
14 | 256 | def propagate_key(_): | 258 | def propagate_key(_): |
15 | 257 | self.archive.signing_key_owner = default_ppa.signing_key_owner | 259 | self.archive.signing_key_owner = default_ppa.signing_key_owner |
16 | @@ -274,8 +276,15 @@ class ArchiveGPGSigningKey(SignableArchive): | |||
17 | 274 | propagate_key(None) | 276 | propagate_key(None) |
18 | 275 | return | 277 | return |
19 | 276 | 278 | ||
22 | 277 | key_displayname = ( | 279 | # XXX cjwatson 2021-12-17: If we need key generation for other |
23 | 278 | "Launchpad PPA for %s" % self.archive.owner.displayname) | 280 | # archive purposes (PRIMARY/PARTNER) then we should extend this, and |
24 | 281 | # perhaps push it down to a property of the archive. | ||
25 | 282 | if self.archive.is_copy: | ||
26 | 283 | key_displayname = ( | ||
27 | 284 | "Launchpad copy archive %s" % self.archive.reference) | ||
28 | 285 | else: | ||
29 | 286 | key_displayname = ( | ||
30 | 287 | "Launchpad PPA for %s" % self.archive.owner.displayname) | ||
31 | 279 | if getFeatureFlag(PUBLISHER_GPG_USES_SIGNING_SERVICE): | 288 | if getFeatureFlag(PUBLISHER_GPG_USES_SIGNING_SERVICE): |
32 | 280 | try: | 289 | try: |
33 | 281 | signing_key = getUtility(ISigningKeySet).generate( | 290 | signing_key = getUtility(ISigningKeySet).generate( |
34 | diff --git a/lib/lp/archivepublisher/tests/archive-signing.txt b/lib/lp/archivepublisher/tests/archive-signing.txt | |||
35 | index f142a01..ced9aa5 100644 | |||
36 | --- a/lib/lp/archivepublisher/tests/archive-signing.txt | |||
37 | +++ b/lib/lp/archivepublisher/tests/archive-signing.txt | |||
38 | @@ -31,7 +31,7 @@ We will set up and use the test-keyserver. | |||
39 | 31 | Querying 'pending signing key' PPAs | 31 | Querying 'pending signing key' PPAs |
40 | 32 | ----------------------------------- | 32 | ----------------------------------- |
41 | 33 | 33 | ||
43 | 34 | `IArchiveSet.getPPAsPendingSigningKey` allows call-sites to query for | 34 | `IArchiveSet.getArchivesPendingSigningKey` allows call-sites to query for |
44 | 35 | PPA pending signing key generation. | 35 | PPA pending signing key generation. |
45 | 36 | 36 | ||
46 | 37 | >>> from lp.registry.interfaces.person import IPersonSet | 37 | >>> from lp.registry.interfaces.person import IPersonSet |
47 | @@ -40,14 +40,14 @@ PPA pending signing key generation. | |||
48 | 40 | Only PPAs with at least one source publication are considered. | 40 | Only PPAs with at least one source publication are considered. |
49 | 41 | 41 | ||
50 | 42 | >>> archive_set = getUtility(IArchiveSet) | 42 | >>> archive_set = getUtility(IArchiveSet) |
52 | 43 | >>> for ppa in archive_set.getPPAsPendingSigningKey(): | 43 | >>> for ppa in archive_set.getArchivesPendingSigningKey(): |
53 | 44 | ... print(ppa.displayname) | 44 | ... print(ppa.displayname) |
54 | 45 | PPA for Celso Providelo | 45 | PPA for Celso Providelo |
55 | 46 | PPA for Mark Shuttleworth | 46 | PPA for Mark Shuttleworth |
56 | 47 | 47 | ||
57 | 48 | The PPA for 'No Privileges' user exists, is enabled and has no | 48 | The PPA for 'No Privileges' user exists, is enabled and has no |
58 | 49 | signing, but it also does not contain any source publications, that's | 49 | signing, but it also does not contain any source publications, that's |
60 | 50 | why it's skipped in the getPPAsPendingSigningKey() results. | 50 | why it's skipped in the getArchivesPendingSigningKey() results. |
61 | 51 | 51 | ||
62 | 52 | >>> cprov = getUtility(IPersonSet).getByName('cprov') | 52 | >>> cprov = getUtility(IPersonSet).getByName('cprov') |
63 | 53 | >>> no_priv = getUtility(IPersonSet).getByName('no-priv') | 53 | >>> no_priv = getUtility(IPersonSet).getByName('no-priv') |
64 | @@ -71,7 +71,7 @@ we copy an arbitrary source into it. | |||
65 | 71 | >>> copied_sources = a_source.copyTo( | 71 | >>> copied_sources = a_source.copyTo( |
66 | 72 | ... a_source.distroseries, a_source.pocket, no_priv.archive) | 72 | ... a_source.distroseries, a_source.pocket, no_priv.archive) |
67 | 73 | 73 | ||
69 | 74 | >>> for ppa in archive_set.getPPAsPendingSigningKey(): | 74 | >>> for ppa in archive_set.getArchivesPendingSigningKey(): |
70 | 75 | ... print(ppa.displayname) | 75 | ... print(ppa.displayname) |
71 | 76 | PPA for Celso Providelo | 76 | PPA for Celso Providelo |
72 | 77 | PPA for Mark Shuttleworth | 77 | PPA for Mark Shuttleworth |
73 | @@ -81,7 +81,7 @@ Disabled PPAs are excluded from the 'PendingSigningKey' pool: | |||
74 | 81 | 81 | ||
75 | 82 | >>> no_priv.archive.disable() | 82 | >>> no_priv.archive.disable() |
76 | 83 | 83 | ||
78 | 84 | >>> for ppa in archive_set.getPPAsPendingSigningKey(): | 84 | >>> for ppa in archive_set.getArchivesPendingSigningKey(): |
79 | 85 | ... print(ppa.displayname) | 85 | ... print(ppa.displayname) |
80 | 86 | PPA for Celso Providelo | 86 | PPA for Celso Providelo |
81 | 87 | PPA for Mark Shuttleworth | 87 | PPA for Mark Shuttleworth |
82 | @@ -111,10 +111,34 @@ And use it as the Mark's PPA signing key. | |||
83 | 111 | 111 | ||
84 | 112 | It will exclude Mark's PPA from the 'PendingSigningKey' pool as well. | 112 | It will exclude Mark's PPA from the 'PendingSigningKey' pool as well. |
85 | 113 | 113 | ||
87 | 114 | >>> for ppa in archive_set.getPPAsPendingSigningKey(): | 114 | >>> for ppa in archive_set.getArchivesPendingSigningKey(): |
88 | 115 | ... print(ppa.displayname) | 115 | ... print(ppa.displayname) |
89 | 116 | PPA for Celso Providelo | 116 | PPA for Celso Providelo |
90 | 117 | 117 | ||
91 | 118 | We can also query for copy archives. | ||
92 | 119 | |||
93 | 120 | >>> from lp.soyuz.enums import ArchivePurpose | ||
94 | 121 | >>> rebuild_archive = factory.makeArchive( | ||
95 | 122 | ... distribution=cprov.archive.distribution, name='test-rebuild', | ||
96 | 123 | ... displayname='Test rebuild', purpose=ArchivePurpose.COPY) | ||
97 | 124 | >>> _ = a_source.copyTo( | ||
98 | 125 | ... a_source.distroseries, a_source.pocket, rebuild_archive) | ||
99 | 126 | >>> for archive in archive_set.getArchivesPendingSigningKey( | ||
100 | 127 | ... purpose=ArchivePurpose.COPY): | ||
101 | 128 | ... print(archive.displayname) | ||
102 | 129 | Test rebuild | ||
103 | 130 | |||
104 | 131 | Set up a signing key for the new test rebuild archive, and after that it no | ||
105 | 132 | longer shows up as pending signing key generation. | ||
106 | 133 | |||
107 | 134 | >>> rebuild_archive.signing_key_owner = a_key.owner | ||
108 | 135 | >>> rebuild_archive.signing_key_fingerprint = a_key.fingerprint | ||
109 | 136 | >>> for archive in archive_set.getArchivesPendingSigningKey( | ||
110 | 137 | ... purpose=ArchivePurpose.COPY): | ||
111 | 138 | ... print(archive.displayname) | ||
112 | 139 | >>> rebuild_archive.signing_key_owner = None | ||
113 | 140 | >>> rebuild_archive.signing_key_fingerprint = None | ||
114 | 141 | |||
115 | 118 | 142 | ||
116 | 119 | Generating a PPA signing key | 143 | Generating a PPA signing key |
117 | 120 | ---------------------------- | 144 | ---------------------------- |
118 | @@ -270,7 +294,6 @@ As documented in archive.txt, when a named-ppa is created it is | |||
119 | 270 | already configured to used the same signing-key created for the | 294 | already configured to used the same signing-key created for the |
120 | 271 | default PPA. We will create a named-ppa for Celso. | 295 | default PPA. We will create a named-ppa for Celso. |
121 | 272 | 296 | ||
122 | 273 | >>> from lp.soyuz.enums import ArchivePurpose | ||
123 | 274 | >>> named_ppa = getUtility(IArchiveSet).new( | 297 | >>> named_ppa = getUtility(IArchiveSet).new( |
124 | 275 | ... owner=cprov, purpose=ArchivePurpose.PPA, name='boing') | 298 | ... owner=cprov, purpose=ArchivePurpose.PPA, name='boing') |
125 | 276 | 299 | ||
126 | @@ -359,6 +382,11 @@ named after the user, even if the default PPA name is something different. | |||
127 | 359 | >>> print(named_ppa.signing_key.fingerprint) | 382 | >>> print(named_ppa.signing_key.fingerprint) |
128 | 360 | 447DBF38C4F9C4ED752246B77D88913717B05A8F | 383 | 447DBF38C4F9C4ED752246B77D88913717B05A8F |
129 | 361 | 384 | ||
130 | 385 | Keys generated for copy archives use a different naming scheme. | ||
131 | 386 | |||
132 | 387 | >>> IArchiveGPGSigningKey(rebuild_archive).generateSigningKey() | ||
133 | 388 | Generating: Launchpad copy archive ubuntu/test-rebuild | ||
134 | 389 | |||
135 | 362 | Restore the original functionality of GPGHandler. | 390 | Restore the original functionality of GPGHandler. |
136 | 363 | 391 | ||
137 | 364 | >>> naked_gpghandler.generateKey = real_key_generator | 392 | >>> naked_gpghandler.generateKey = real_key_generator |
138 | diff --git a/lib/lp/soyuz/interfaces/archive.py b/lib/lp/soyuz/interfaces/archive.py | |||
139 | index d01ebdf..a3de895 100644 | |||
140 | --- a/lib/lp/soyuz/interfaces/archive.py | |||
141 | +++ b/lib/lp/soyuz/interfaces/archive.py | |||
142 | @@ -2416,10 +2416,12 @@ class IArchiveSet(Interface): | |||
143 | 2416 | def getPPADistributionsForUser(user): | 2416 | def getPPADistributionsForUser(user): |
144 | 2417 | """Return the `Distribution`s of all PPAs for the given user.""" | 2417 | """Return the `Distribution`s of all PPAs for the given user.""" |
145 | 2418 | 2418 | ||
148 | 2419 | def getPPAsPendingSigningKey(): | 2419 | def getArchivesPendingSigningKey(purpose=ArchivePurpose.PPA): |
149 | 2420 | """Return all PPAs pending signing key generation. | 2420 | """Return all archives with `purpose` pending signing key generation. |
150 | 2421 | 2421 | ||
151 | 2422 | The result is ordered by archive creation date. | 2422 | The result is ordered by archive creation date. |
152 | 2423 | |||
153 | 2424 | :param purpose: Only return archives with this `ArchivePurpose`. | ||
154 | 2423 | """ | 2425 | """ |
155 | 2424 | 2426 | ||
156 | 2425 | def getLatestPPASourcePublicationsForDistribution(distribution): | 2427 | def getLatestPPASourcePublicationsForDistribution(distribution): |
157 | diff --git a/lib/lp/soyuz/model/archive.py b/lib/lp/soyuz/model/archive.py | |||
158 | index ae95cf9..50ed7aa 100644 | |||
159 | --- a/lib/lp/soyuz/model/archive.py | |||
160 | +++ b/lib/lp/soyuz/model/archive.py | |||
161 | @@ -2819,7 +2819,7 @@ class ArchiveSet: | |||
162 | 2819 | self._getPPAsForUserClause(user)) | 2819 | self._getPPAsForUserClause(user)) |
163 | 2820 | return result.config(distinct=True) | 2820 | return result.config(distinct=True) |
164 | 2821 | 2821 | ||
166 | 2822 | def getPPAsPendingSigningKey(self): | 2822 | def getArchivesPendingSigningKey(self, purpose=ArchivePurpose.PPA): |
167 | 2823 | """See `IArchiveSet`.""" | 2823 | """See `IArchiveSet`.""" |
168 | 2824 | origin = ( | 2824 | origin = ( |
169 | 2825 | Archive, | 2825 | Archive, |
170 | @@ -2828,7 +2828,7 @@ class ArchiveSet: | |||
171 | 2828 | results = IStore(Archive).using(*origin).find( | 2828 | results = IStore(Archive).using(*origin).find( |
172 | 2829 | Archive, | 2829 | Archive, |
173 | 2830 | Archive.signing_key_fingerprint == None, | 2830 | Archive.signing_key_fingerprint == None, |
175 | 2831 | Archive.purpose == ArchivePurpose.PPA, Archive._enabled == True) | 2831 | Archive.purpose == purpose, Archive._enabled == True) |
176 | 2832 | results.order_by(Archive.date_created) | 2832 | results.order_by(Archive.date_created) |
177 | 2833 | return results.config(distinct=True) | 2833 | return results.config(distinct=True) |
178 | 2834 | 2834 | ||
179 | diff --git a/lib/lp/soyuz/scripts/ppakeygenerator.py b/lib/lp/soyuz/scripts/ppakeygenerator.py | |||
180 | index 88e1d84..1b650f1 100644 | |||
181 | --- a/lib/lp/soyuz/scripts/ppakeygenerator.py | |||
182 | +++ b/lib/lp/soyuz/scripts/ppakeygenerator.py | |||
183 | @@ -1,4 +1,4 @@ | |||
185 | 1 | # Copyright 2009-2019 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2021 Canonical Ltd. This software is licensed under the |
186 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
187 | 3 | 3 | ||
188 | 4 | __all__ = [ | 4 | __all__ = [ |
189 | @@ -14,6 +14,7 @@ from lp.services.scripts.base import ( | |||
190 | 14 | LaunchpadCronScript, | 14 | LaunchpadCronScript, |
191 | 15 | LaunchpadScriptFailure, | 15 | LaunchpadScriptFailure, |
192 | 16 | ) | 16 | ) |
193 | 17 | from lp.soyuz.enums import ArchivePurpose | ||
194 | 17 | from lp.soyuz.interfaces.archive import IArchiveSet | 18 | from lp.soyuz.interfaces.archive import IArchiveSet |
195 | 18 | 19 | ||
196 | 19 | 20 | ||
197 | @@ -26,6 +27,9 @@ class PPAKeyGenerator(LaunchpadCronScript): | |||
198 | 26 | self.parser.add_option( | 27 | self.parser.add_option( |
199 | 27 | "-A", "--archive", | 28 | "-A", "--archive", |
200 | 28 | help="The reference of the archive whose key should be generated.") | 29 | help="The reference of the archive whose key should be generated.") |
201 | 30 | self.parser.add_option( | ||
202 | 31 | "--copy-archives", action="store_true", default=False, | ||
203 | 32 | help="Run only over COPY archives.") | ||
204 | 29 | 33 | ||
205 | 30 | def generateKey(self, archive): | 34 | def generateKey(self, archive): |
206 | 31 | """Generate a signing key for the given archive.""" | 35 | """Generate a signing key for the given archive.""" |
207 | @@ -38,9 +42,9 @@ class PPAKeyGenerator(LaunchpadCronScript): | |||
208 | 38 | 42 | ||
209 | 39 | def main(self): | 43 | def main(self): |
210 | 40 | """Generate signing keys for the selected PPAs.""" | 44 | """Generate signing keys for the selected PPAs.""" |
211 | 45 | archive_set = getUtility(IArchiveSet) | ||
212 | 41 | if self.options.archive is not None: | 46 | if self.options.archive is not None: |
215 | 42 | archive = getUtility(IArchiveSet).getByReference( | 47 | archive = archive_set.getByReference(self.options.archive) |
214 | 43 | self.options.archive) | ||
216 | 44 | if archive is None: | 48 | if archive is None: |
217 | 45 | raise LaunchpadScriptFailure( | 49 | raise LaunchpadScriptFailure( |
218 | 46 | "No archive named '%s' could be found." | 50 | "No archive named '%s' could be found." |
219 | @@ -51,9 +55,11 @@ class PPAKeyGenerator(LaunchpadCronScript): | |||
220 | 51 | % (archive.reference, archive.displayname, | 55 | % (archive.reference, archive.displayname, |
221 | 52 | archive.signing_key_fingerprint)) | 56 | archive.signing_key_fingerprint)) |
222 | 53 | archives = [archive] | 57 | archives = [archive] |
223 | 58 | elif self.options.copy_archives: | ||
224 | 59 | archives = list(archive_set.getArchivesPendingSigningKey( | ||
225 | 60 | purpose=ArchivePurpose.COPY)) | ||
226 | 54 | else: | 61 | else: |
229 | 55 | archive_set = getUtility(IArchiveSet) | 62 | archives = list(archive_set.getArchivesPendingSigningKey()) |
228 | 56 | archives = list(archive_set.getPPAsPendingSigningKey()) | ||
230 | 57 | 63 | ||
231 | 58 | for archive in archives: | 64 | for archive in archives: |
232 | 59 | self.generateKey(archive) | 65 | self.generateKey(archive) |
233 | diff --git a/lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py b/lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py | |||
234 | index 182f64a..0ad8a7d 100644 | |||
235 | --- a/lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py | |||
236 | +++ b/lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py | |||
237 | @@ -1,4 +1,4 @@ | |||
239 | 1 | # Copyright 2009-2019 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2021 Canonical Ltd. This software is licensed under the |
240 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
241 | 3 | 3 | ||
242 | 4 | """`PPAKeyGenerator` script class tests.""" | 4 | """`PPAKeyGenerator` script class tests.""" |
243 | @@ -10,14 +10,15 @@ from lp.registry.interfaces.gpg import IGPGKeySet | |||
244 | 10 | from lp.registry.interfaces.person import IPersonSet | 10 | from lp.registry.interfaces.person import IPersonSet |
245 | 11 | from lp.services.propertycache import get_property_cache | 11 | from lp.services.propertycache import get_property_cache |
246 | 12 | from lp.services.scripts.base import LaunchpadScriptFailure | 12 | from lp.services.scripts.base import LaunchpadScriptFailure |
247 | 13 | from lp.soyuz.enums import ArchivePurpose | ||
248 | 13 | from lp.soyuz.interfaces.archive import IArchiveSet | 14 | from lp.soyuz.interfaces.archive import IArchiveSet |
249 | 14 | from lp.soyuz.scripts.ppakeygenerator import PPAKeyGenerator | 15 | from lp.soyuz.scripts.ppakeygenerator import PPAKeyGenerator |
251 | 15 | from lp.testing import TestCase | 16 | from lp.testing import TestCaseWithFactory |
252 | 16 | from lp.testing.faketransaction import FakeTransaction | 17 | from lp.testing.faketransaction import FakeTransaction |
253 | 17 | from lp.testing.layers import LaunchpadZopelessLayer | 18 | from lp.testing.layers import LaunchpadZopelessLayer |
254 | 18 | 19 | ||
255 | 19 | 20 | ||
257 | 20 | class TestPPAKeyGenerator(TestCase): | 21 | class TestPPAKeyGenerator(TestCaseWithFactory): |
258 | 21 | layer = LaunchpadZopelessLayer | 22 | layer = LaunchpadZopelessLayer |
259 | 22 | 23 | ||
260 | 23 | def _fixArchiveForKeyGeneration(self, archive): | 24 | def _fixArchiveForKeyGeneration(self, archive): |
261 | @@ -29,7 +30,8 @@ class TestPPAKeyGenerator(TestCase): | |||
262 | 29 | ubuntutest = getUtility(IDistributionSet).getByName('ubuntutest') | 30 | ubuntutest = getUtility(IDistributionSet).getByName('ubuntutest') |
263 | 30 | archive.distribution = ubuntutest | 31 | archive.distribution = ubuntutest |
264 | 31 | 32 | ||
266 | 32 | def _getKeyGenerator(self, archive_reference=None, txn=None): | 33 | def _getKeyGenerator(self, archive_reference=None, copy_archives=False, |
267 | 34 | txn=None): | ||
268 | 33 | """Return a `PPAKeyGenerator` instance. | 35 | """Return a `PPAKeyGenerator` instance. |
269 | 34 | 36 | ||
270 | 35 | Monkey-patch the script object with a fake transaction manager | 37 | Monkey-patch the script object with a fake transaction manager |
271 | @@ -40,6 +42,8 @@ class TestPPAKeyGenerator(TestCase): | |||
272 | 40 | 42 | ||
273 | 41 | if archive_reference is not None: | 43 | if archive_reference is not None: |
274 | 42 | test_args.extend(['-A', archive_reference]) | 44 | test_args.extend(['-A', archive_reference]) |
275 | 45 | if copy_archives: | ||
276 | 46 | test_args.append('--copy-archives') | ||
277 | 43 | 47 | ||
278 | 44 | key_generator = PPAKeyGenerator( | 48 | key_generator = PPAKeyGenerator( |
279 | 45 | name='ppa-generate-keys', test_args=test_args) | 49 | name='ppa-generate-keys', test_args=test_args) |
280 | @@ -109,7 +113,7 @@ class TestPPAKeyGenerator(TestCase): | |||
281 | 109 | The 'signing_key' for all 'pending-signing-key' PPAs are generated | 113 | The 'signing_key' for all 'pending-signing-key' PPAs are generated |
282 | 110 | and the transaction is committed once for each PPA. | 114 | and the transaction is committed once for each PPA. |
283 | 111 | """ | 115 | """ |
285 | 112 | archives = list(getUtility(IArchiveSet).getPPAsPendingSigningKey()) | 116 | archives = list(getUtility(IArchiveSet).getArchivesPendingSigningKey()) |
286 | 113 | 117 | ||
287 | 114 | for archive in archives: | 118 | for archive in archives: |
288 | 115 | self._fixArchiveForKeyGeneration(archive) | 119 | self._fixArchiveForKeyGeneration(archive) |
289 | @@ -123,3 +127,33 @@ class TestPPAKeyGenerator(TestCase): | |||
290 | 123 | self.assertIsNotNone(archive.signing_key_fingerprint) | 127 | self.assertIsNotNone(archive.signing_key_fingerprint) |
291 | 124 | 128 | ||
292 | 125 | self.assertEqual(txn.commit_count, len(archives)) | 129 | self.assertEqual(txn.commit_count, len(archives)) |
293 | 130 | |||
294 | 131 | def testGenerateKeyForAllCopyArchives(self): | ||
295 | 132 | """Signing key generation for all PPAs. | ||
296 | 133 | |||
297 | 134 | The 'signing_key' for all 'pending-signing-key' PPAs are generated | ||
298 | 135 | and the transaction is committed once for each PPA. | ||
299 | 136 | """ | ||
300 | 137 | for _ in range(3): | ||
301 | 138 | rebuild = self.factory.makeArchive( | ||
302 | 139 | distribution=getUtility(IDistributionSet).getByName( | ||
303 | 140 | 'ubuntutest'), | ||
304 | 141 | purpose=ArchivePurpose.COPY) | ||
305 | 142 | self.factory.makeSourcePackagePublishingHistory(archive=rebuild) | ||
306 | 143 | |||
307 | 144 | archives = list(getUtility(IArchiveSet).getArchivesPendingSigningKey( | ||
308 | 145 | purpose=ArchivePurpose.COPY)) | ||
309 | 146 | self.assertNotEqual([], archives) | ||
310 | 147 | |||
311 | 148 | for archive in archives: | ||
312 | 149 | self._fixArchiveForKeyGeneration(archive) | ||
313 | 150 | self.assertIsNone(archive.signing_key_fingerprint) | ||
314 | 151 | |||
315 | 152 | txn = FakeTransaction() | ||
316 | 153 | key_generator = self._getKeyGenerator(copy_archives=True, txn=txn) | ||
317 | 154 | key_generator.main() | ||
318 | 155 | |||
319 | 156 | for archive in archives: | ||
320 | 157 | self.assertIsNotNone(archive.signing_key_fingerprint) | ||
321 | 158 | |||
322 | 159 | self.assertEqual(txn.commit_count, len(archives)) |