Merge lp:~jelmer/launchpad/bug471148 into lp:launchpad/db-devel
- bug471148
- Merge into db-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Jelmer Vernooij | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~jelmer/launchpad/bug471148 | ||||
Merge into: | lp:launchpad/db-devel | ||||
Diff against target: |
711 lines (+423/-18) 18 files modified
database/sampledata/current-dev.sql (+5/-4) database/sampledata/current.sql (+5/-4) database/schema/patch-2207-35-0.sql (+8/-0) database/schema/security.cfg (+2/-2) lib/lp/soyuz/browser/archive.py (+1/-1) lib/lp/soyuz/configure.zcml (+2/-1) lib/lp/soyuz/interfaces/archive.py (+3/-0) lib/lp/soyuz/interfaces/archivearch.py (+11/-0) lib/lp/soyuz/interfaces/processor.py (+24/-1) lib/lp/soyuz/model/archive.py (+35/-0) lib/lp/soyuz/model/archivearch.py (+16/-0) lib/lp/soyuz/model/processor.py (+12/-0) lib/lp/soyuz/model/publishing.py (+25/-5) lib/lp/soyuz/tests/test_archive.py (+53/-0) lib/lp/soyuz/tests/test_archivearch.py (+57/-0) lib/lp/soyuz/tests/test_processor.py (+32/-0) lib/lp/soyuz/tests/test_publishing.py (+99/-0) lib/lp/testing/factory.py (+33/-0) |
||||
To merge this branch: | bzr merge lp:~jelmer/launchpad/bug471148 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Björn Tillenius (community) | db | Approve | |
Stuart Bishop (community) | db | Approve | |
Paul Hummer (community) | code | Approve | |
Review via email: mp+20142@code.launchpad.net |
This proposal supersedes a proposal from 2010-02-24.
Commit message
Add restricted flag to processor families and allow them to be overriden on a per-archive basis.
Description of the change
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal | # |
Jeroen T. Vermeulen (jtv) wrote : Posted in a previous version of this proposal | # |
It looks as if this diff got polluted with extraneous changes.
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal | # |
Hi Jeroen,
On Wed, 2010-02-24 at 18:18 +0000, Jeroen T. Vermeulen wrote:
> It looks as if this diff got polluted with extraneous changes.
The sampledata doesn't appear to have been regenerated a couple of times
after some other schema changes landed, and that causes the diff to
database/
change I've made to the sample data is to add a ARM processor family
that has the new restricted column set to true. Other than that, this is
a fairly simple branch against db-devel.
If you'd rather have me submit a separate branch that just runs "make
newsampledata" in db-devel so that the diff for this branch isn't
cluttered by it, please let me know.
Cheers,
Jelmer
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal | # |
Muharem has now submitted a separate branch which just updates the existing sampledata, that should make the diff for this branch a fair bit smaller.
Muharem Hrnjadovic (al-maisan) wrote : Posted in a previous version of this proposal | # |
Yep, it's lp:~al-maisan/launchpad/sampledata-update and it was just approved.
Paul Hummer (rockstar) wrote : | # |
<rockstar> jelmer, is this diff up to date? Does it have a dependent branch?
<jelmer> rockstar: the bug471148 one? That's current now
<rockstar> jelmer, okay.
<jelmer> rockstar: It's a fair bit smaller now that Muharems prerequisite branch has landed.
<rockstar> jelmer, you should set the prerequisite branch on the mp anyway, because it's informational.
<jelmer> rockstar: Even if that branch has already landed?
<rockstar> jelmer, yeah, it's still a good idea to say "I based my work off of this work."
<rockstar> Not a necessity, but for history's sake.
<jelmer> rockstar: Ah, that makes sense. I'll keep that in mind for next time.
<rockstar> jelmer, your tests need comments/
<rockstar> lib/lp/
<rockstar> Actually, it looks like some of the tests have docstrings, so you'll probably just need to add the docstrings to the ones that lack them.
<jelmer> ok
<rockstar> jelmer, good on you for adding factory methods for your new work.
<jelmer> rockstar: Thanks
<rockstar> jelmer, other than the missing docstrings, this looks like very good work.
Stuart Bishop (stub) wrote : | # |
So if there are no ArchArchive entries, the archive is build with all the non-retricted architectures.
A less generic name might be nice, but I can't think of a better term right now.
Looks fine anyway. Patch number patch-2207-
Björn Tillenius (bjornt) wrote : | # |
I also would like to see a better name, but can't think of any right now.
Preview Diff
1 | === modified file 'database/sampledata/current-dev.sql' |
2 | --- database/sampledata/current-dev.sql 2010-02-25 08:39:19 +0000 |
3 | +++ database/sampledata/current-dev.sql 2010-02-26 23:30:37 +0000 |
4 | @@ -8143,10 +8143,11 @@ |
5 | |
6 | ALTER TABLE processorfamily DISABLE TRIGGER ALL; |
7 | |
8 | -INSERT INTO processorfamily (id, name, title, description) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!'); |
9 | -INSERT INTO processorfamily (id, name, title, description) VALUES (2, 'powerpc', 'PowerPC compatible systems, G3 G4 etc', 'An architecture conceived by Motorola and developed further in cooperation with IBM. Was used very successfully by Apple for their PowerMac range, until 2007.'); |
10 | -INSERT INTO processorfamily (id, name, title, description) VALUES (3, 'amd64', 'AMD64 and Intel EM64T and compatible systems', 'A 64-bit extension to the venerable x86 architecture, pioneered by AMD and later adopted by Intel as well.'); |
11 | -INSERT INTO processorfamily (id, name, title, description) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors'); |
12 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!', false); |
13 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (2, 'powerpc', 'PowerPC compatible systems, G3 G4 etc', 'An architecture conceived by Motorola and developed further in cooperation with IBM. Was used very successfully by Apple for their PowerMac range, until 2007.', false); |
14 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (3, 'amd64', 'AMD64 and Intel EM64T and compatible systems', 'A 64-bit extension to the venerable x86 architecture, pioneered by AMD and later adopted by Intel as well.', false); |
15 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors', false); |
16 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (5, 'arm', 'ARM Processors', 'The ARM and compatible processors', true); |
17 | |
18 | |
19 | ALTER TABLE processorfamily ENABLE TRIGGER ALL; |
20 | |
21 | === modified file 'database/sampledata/current.sql' |
22 | --- database/sampledata/current.sql 2010-02-25 08:39:19 +0000 |
23 | +++ database/sampledata/current.sql 2010-02-26 23:30:37 +0000 |
24 | @@ -8039,10 +8039,11 @@ |
25 | |
26 | ALTER TABLE processorfamily DISABLE TRIGGER ALL; |
27 | |
28 | -INSERT INTO processorfamily (id, name, title, description) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!'); |
29 | -INSERT INTO processorfamily (id, name, title, description) VALUES (2, 'powerpc', 'PowerPC compatible systems, G3 G4 etc', 'An architecture conceived by Motorola and developed further in cooperation with IBM. Was used very successfully by Apple for their PowerMac range, until 2007.'); |
30 | -INSERT INTO processorfamily (id, name, title, description) VALUES (3, 'amd64', 'AMD64 and Intel EM64T and compatible systems', 'A 64-bit extension to the venerable x86 architecture, pioneered by AMD and later adopted by Intel as well.'); |
31 | -INSERT INTO processorfamily (id, name, title, description) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors'); |
32 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!', false); |
33 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (2, 'powerpc', 'PowerPC compatible systems, G3 G4 etc', 'An architecture conceived by Motorola and developed further in cooperation with IBM. Was used very successfully by Apple for their PowerMac range, until 2007.', false); |
34 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (3, 'amd64', 'AMD64 and Intel EM64T and compatible systems', 'A 64-bit extension to the venerable x86 architecture, pioneered by AMD and later adopted by Intel as well.', false); |
35 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors', false); |
36 | +INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (5, 'arm', 'ARM Processors', 'The ARM and compatible processors', true); |
37 | |
38 | |
39 | ALTER TABLE processorfamily ENABLE TRIGGER ALL; |
40 | |
41 | === added file 'database/schema/patch-2207-35-0.sql' |
42 | --- database/schema/patch-2207-35-0.sql 1970-01-01 00:00:00 +0000 |
43 | +++ database/schema/patch-2207-35-0.sql 2010-02-26 23:30:37 +0000 |
44 | @@ -0,0 +1,8 @@ |
45 | +-- Copyright 2010 Canonical Ltd. This software is licensed under the |
46 | +-- GNU Affero General Public License version 3 (see the file LICENSE). |
47 | + |
48 | +SET client_min_messages=ERROR; |
49 | + |
50 | +ALTER TABLE processorfamily ADD COLUMN restricted boolean DEFAULT FALSE NOT NULL; |
51 | + |
52 | +INSERT INTO LaunchpadDatabaseRevision VALUES (2207, 35, 0); |
53 | |
54 | === modified file 'database/schema/security.cfg' |
55 | --- database/schema/security.cfg 2010-02-22 12:44:29 +0000 |
56 | +++ database/schema/security.cfg 2010-02-26 23:30:37 +0000 |
57 | @@ -125,7 +125,7 @@ |
58 | public.archive = SELECT, INSERT, UPDATE |
59 | public.archiveauthtoken = SELECT, INSERT, UPDATE |
60 | public.archivesubscriber = SELECT, INSERT, UPDATE |
61 | -public.archivearch = SELECT, INSERT, UPDATE |
62 | +public.archivearch = SELECT, INSERT, UPDATE, DELETE |
63 | public.archivedependency = SELECT, INSERT, DELETE |
64 | public.archivepermission = SELECT, INSERT, UPDATE, DELETE |
65 | public.authtoken = SELECT, INSERT, UPDATE, DELETE |
66 | @@ -916,7 +916,7 @@ |
67 | # certain processes, such as the librarian tables. This group is deprecated - |
68 | # access should be explicitly granted to users. |
69 | public.archive = SELECT, INSERT, UPDATE |
70 | -public.archivearch = SELECT, INSERT, UPDATE |
71 | +public.archivearch = SELECT, INSERT, UPDATE, DELETE |
72 | public.binarypackagerelease = SELECT, INSERT, UPDATE |
73 | public.binarypackagefile = SELECT, INSERT, UPDATE |
74 | public.binarypackagefilepublishing = SELECT, INSERT, UPDATE |
75 | |
76 | === modified file 'lib/lp/soyuz/browser/archive.py' |
77 | --- lib/lp/soyuz/browser/archive.py 2010-02-25 16:49:16 +0000 |
78 | +++ lib/lp/soyuz/browser/archive.py 2010-02-26 23:30:37 +0000 |
79 | @@ -1790,7 +1790,7 @@ |
80 | |
81 | field_names = ['enabled', 'private', 'require_virtualized', |
82 | 'buildd_secret', 'authorized_size', 'relative_build_score', |
83 | - 'external_dependencies'] |
84 | + 'external_dependencies', 'arm_builds_allowed'] |
85 | |
86 | custom_widget('external_dependencies', TextAreaWidget, height=3) |
87 | |
88 | |
89 | === modified file 'lib/lp/soyuz/configure.zcml' |
90 | --- lib/lp/soyuz/configure.zcml 2010-02-25 22:41:23 +0000 |
91 | +++ lib/lp/soyuz/configure.zcml 2010-02-26 23:30:37 +0000 |
92 | @@ -400,7 +400,8 @@ |
93 | <require |
94 | permission="launchpad.Edit" |
95 | interface="lp.soyuz.interfaces.archive.IArchiveEdit" |
96 | - set_attributes="description displayname publish"/> |
97 | + set_attributes="description displayname arm_builds_allowed |
98 | + publish"/> |
99 | <require |
100 | permission="launchpad.Commercial" |
101 | set_attributes="authorized_size buildd_secret |
102 | |
103 | === modified file 'lib/lp/soyuz/interfaces/archive.py' |
104 | --- lib/lp/soyuz/interfaces/archive.py 2010-02-25 16:49:16 +0000 |
105 | +++ lib/lp/soyuz/interfaces/archive.py 2010-02-26 23:30:37 +0000 |
106 | @@ -1090,6 +1090,9 @@ |
107 | def disable(): |
108 | """Disable the archive.""" |
109 | |
110 | + arm_builds_allowed = Bool( |
111 | + title=_("Allow ARM builds for this archive")) |
112 | + |
113 | |
114 | class IArchive(IArchivePublic, IArchiveAppend, IArchiveEdit, IArchiveView): |
115 | """Main Archive interface.""" |
116 | |
117 | === modified file 'lib/lp/soyuz/interfaces/archivearch.py' |
118 | --- lib/lp/soyuz/interfaces/archivearch.py 2009-06-25 04:06:00 +0000 |
119 | +++ lib/lp/soyuz/interfaces/archivearch.py 2010-02-26 23:30:37 +0000 |
120 | @@ -62,3 +62,14 @@ |
121 | |
122 | :return: A (potentially empty) result set of `IArchiveArch` instances. |
123 | """ |
124 | + |
125 | + def getRestrictedfamilies(archive): |
126 | + """All restricted processor families, paired with `ArchiveArch` |
127 | + instances if associated with `archive`. |
128 | + |
129 | + :return: A sequence containing a (`ProcessorFamily`, `ArchiveArch`) |
130 | + 2-tuple for each processor family. |
131 | + The second value in the tuple will be None if the given `archive` |
132 | + is not associated with the `ProcessorFamily` yet. |
133 | + """ |
134 | + |
135 | |
136 | === modified file 'lib/lp/soyuz/interfaces/processor.py' |
137 | --- lib/lp/soyuz/interfaces/processor.py 2009-06-25 04:06:00 +0000 |
138 | +++ lib/lp/soyuz/interfaces/processor.py 2010-02-26 23:30:37 +0000 |
139 | @@ -13,7 +13,10 @@ |
140 | 'IProcessorFamilySet', |
141 | ] |
142 | |
143 | +from canonical.launchpad import _ |
144 | + |
145 | from zope.interface import Interface, Attribute |
146 | +from zope.schema import Bool |
147 | |
148 | class IProcessor(Interface): |
149 | """The SQLObject Processor Interface""" |
150 | @@ -29,11 +32,21 @@ |
151 | name = Attribute("The Processor Family Name") |
152 | title = Attribute("The Processor Family Title") |
153 | description = Attribute("The Processor Name Description") |
154 | - |
155 | processors = Attribute("The Processors in this family.") |
156 | + restricted = Bool(title=_("Whether this family is restricted.")) |
157 | + |
158 | + def addProcessor(name, title, description): |
159 | + """Add a new processor to this family. |
160 | + |
161 | + :param name: Name of the processor |
162 | + :param title: Title of the processor |
163 | + :param description: Description of the processor |
164 | + :return: A `IProcessor` |
165 | + """ |
166 | |
167 | class IProcessorFamilySet(Interface): |
168 | """Operations related to ProcessorFamily instances.""" |
169 | + |
170 | def getByName(name): |
171 | """Return the ProcessorFamily instance with the matching name. |
172 | |
173 | @@ -49,3 +62,13 @@ |
174 | |
175 | :return: A `IProcessorFamily` instance if found, None otherwise. |
176 | """ |
177 | + |
178 | + def new(name, title, description, restricted): |
179 | + """Create a new processor family. |
180 | + |
181 | + :param name: Name of the family. |
182 | + :param title: Title for the family. |
183 | + :param description: Extended description of the family |
184 | + :param restricted: Whether the processor family is restricted |
185 | + :return: a `IProcessorFamily`. |
186 | + """ |
187 | |
188 | === modified file 'lib/lp/soyuz/model/archive.py' |
189 | --- lib/lp/soyuz/model/archive.py 2010-02-18 17:05:50 +0000 |
190 | +++ lib/lp/soyuz/model/archive.py 2010-02-26 23:30:37 +0000 |
191 | @@ -59,6 +59,7 @@ |
192 | IDistributionArchive, InvalidComponent, IPPA, MAIN_ARCHIVE_PURPOSES, |
193 | NoSuchPPA, PocketNotFound, VersionRequiresName, default_name_by_purpose) |
194 | from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthTokenSet |
195 | +from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
196 | from lp.soyuz.interfaces.archivepermission import ( |
197 | ArchivePermissionType, IArchivePermissionSet) |
198 | from lp.soyuz.interfaces.archivesubscriber import ( |
199 | @@ -75,6 +76,7 @@ |
200 | from lp.registry.interfaces.role import IHasOwner |
201 | from lp.soyuz.interfaces.queue import PackageUploadStatus |
202 | from lp.soyuz.interfaces.packagecopyrequest import IPackageCopyRequestSet |
203 | +from lp.soyuz.interfaces.processor import IProcessorFamilySet |
204 | from lp.soyuz.interfaces.publishing import ( |
205 | active_publishing_status, PackagePublishingStatus, IPublishingSet) |
206 | from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet |
207 | @@ -182,6 +184,39 @@ |
208 | external_dependencies = StringCol( |
209 | dbName='external_dependencies', notNull=False, default=None) |
210 | |
211 | + def _get_arm_builds_enabled(self): |
212 | + """Check whether ARM builds are allowed for this archive.""" |
213 | + archive_arch_set = getUtility(IArchiveArchSet) |
214 | + restricted_families = archive_arch_set.getRestrictedfamilies(self) |
215 | + arm = getUtility(IProcessorFamilySet).getByName('arm') |
216 | + for (family, archive_arch) in restricted_families: |
217 | + if family == arm: |
218 | + return (archive_arch is not None) |
219 | + # ARM doesn't exist or isn't restricted. Either way, there is no |
220 | + # need for an explicit association. |
221 | + return False |
222 | + |
223 | + def _set_arm_builds_enabled(self, value): |
224 | + """Set whether ARM builds are enabled for this archive.""" |
225 | + archive_arch_set = getUtility(IArchiveArchSet) |
226 | + restricted_families = archive_arch_set.getRestrictedfamilies(self) |
227 | + arm = getUtility(IProcessorFamilySet).getByName('arm') |
228 | + for (family, archive_arch) in restricted_families: |
229 | + if family == arm: |
230 | + if value: |
231 | + if archive_arch is not None: |
232 | + # ARM builds are already enabled |
233 | + return |
234 | + else: |
235 | + archive_arch_set.new(self, family) |
236 | + else: |
237 | + if archive_arch is not None: |
238 | + Store.of(self).remove(archive_arch) |
239 | + else: |
240 | + pass # ARM builds are already disabled |
241 | + arm_builds_allowed = property(_get_arm_builds_enabled, |
242 | + _set_arm_builds_enabled) |
243 | + |
244 | def _init(self, *args, **kw): |
245 | """Provide the right interface for URL traversal.""" |
246 | SQLBase._init(self, *args, **kw) |
247 | |
248 | === modified file 'lib/lp/soyuz/model/archivearch.py' |
249 | --- lib/lp/soyuz/model/archivearch.py 2009-06-25 04:06:00 +0000 |
250 | +++ lib/lp/soyuz/model/archivearch.py 2010-02-26 23:30:37 +0000 |
251 | @@ -9,9 +9,11 @@ |
252 | |
253 | from lp.soyuz.interfaces.archivearch import ( |
254 | IArchiveArch, IArchiveArchSet) |
255 | +from lp.soyuz.model.processor import ProcessorFamily |
256 | from canonical.launchpad.webapp.interfaces import ( |
257 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) |
258 | |
259 | +from storm.expr import Join, LeftJoin |
260 | from storm.locals import Int, Reference, Storm |
261 | |
262 | |
263 | @@ -55,3 +57,17 @@ |
264 | results = results.order_by(ArchiveArch.id) |
265 | |
266 | return results |
267 | + |
268 | + def getRestrictedfamilies(self, archive): |
269 | + """See `IArchiveArchSet`.""" |
270 | + store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
271 | + origin = ( |
272 | + ProcessorFamily, |
273 | + LeftJoin( |
274 | + ArchiveArch, |
275 | + ArchiveArch.processorfamily == ProcessorFamily.id)) |
276 | + result_set = store.using(*origin).find( |
277 | + (ProcessorFamily, ArchiveArch), |
278 | + (ProcessorFamily.restricted == True)) |
279 | + |
280 | + return result_set.order_by(ProcessorFamily.name) |
281 | |
282 | === modified file 'lib/lp/soyuz/model/processor.py' |
283 | --- lib/lp/soyuz/model/processor.py 2009-06-25 04:06:00 +0000 |
284 | +++ lib/lp/soyuz/model/processor.py 2010-02-26 23:30:37 +0000 |
285 | @@ -10,6 +10,7 @@ |
286 | from zope.interface import implements |
287 | |
288 | from sqlobject import StringCol, ForeignKey, SQLMultipleJoin |
289 | +from storm.locals import Bool |
290 | |
291 | from canonical.database.sqlbase import SQLBase |
292 | |
293 | @@ -39,6 +40,12 @@ |
294 | description = StringCol(dbName='description', notNull=True) |
295 | |
296 | processors = SQLMultipleJoin('Processor', joinColumn='family') |
297 | + restricted = Bool(allow_none=False, default=False) |
298 | + |
299 | + def addProcessor(self, name, title, description): |
300 | + """See `IProcessorFamily`.""" |
301 | + return Processor(family=self, name=name, title=title, |
302 | + description=description) |
303 | |
304 | |
305 | class ProcessorFamilySet: |
306 | @@ -62,3 +69,8 @@ |
307 | # but there is also the possibility that the user specified a name for |
308 | # a non-existent processor. |
309 | return rset.one() |
310 | + |
311 | + def new(self, name, title, description, restricted=False): |
312 | + """See `IProcessorFamily`.""" |
313 | + return ProcessorFamily(name=name, title=title, |
314 | + description=description, restricted=restricted) |
315 | |
316 | === modified file 'lib/lp/soyuz/model/publishing.py' |
317 | --- lib/lp/soyuz/model/publishing.py 2010-02-15 12:59:55 +0000 |
318 | +++ lib/lp/soyuz/model/publishing.py 2010-02-26 23:30:37 +0000 |
319 | @@ -45,14 +45,15 @@ |
320 | LibraryFileAlias, LibraryFileContent) |
321 | from lp.soyuz.model.packagediff import PackageDiff |
322 | from lp.soyuz.interfaces.archive import ArchivePurpose |
323 | +from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
324 | from lp.soyuz.interfaces.component import IComponentSet |
325 | from lp.soyuz.interfaces.queue import PackageUploadStatus |
326 | from lp.soyuz.interfaces.publishing import ( |
327 | - active_publishing_status, IArchiveSafePublisher, |
328 | - IBinaryPackageFilePublishing, IBinaryPackagePublishingHistory, |
329 | - IPublishingEdit, IPublishingSet, ISourcePackageFilePublishing, |
330 | - ISourcePackagePublishingHistory, PackagePublishingPriority, |
331 | - PackagePublishingStatus, PoolFileOverwriteError) |
332 | + active_publishing_status, IBinaryPackageFilePublishing, |
333 | + IBinaryPackagePublishingHistory, IPublishingSet, |
334 | + ISourcePackageFilePublishing, ISourcePackagePublishingHistory, |
335 | + PackagePublishingPriority, PackagePublishingStatus, |
336 | + PoolFileOverwriteError) |
337 | from lp.soyuz.interfaces.build import BuildSetStatus, BuildStatus, IBuildSet |
338 | from lp.soyuz.scripts.changeoverride import ArchiveOverriderError |
339 | from canonical.launchpad.components.decoratedresultset import ( |
340 | @@ -505,6 +506,22 @@ |
341 | the_url = self._proxied_urls((changes_lfa,), self.archive)[0] |
342 | return the_url |
343 | |
344 | + def _getAllowedArchitectures(self, available_archs): |
345 | + """Filter out any restricted architectures not specifically allowed |
346 | + for an archive. |
347 | + |
348 | + :param available_archs: Architectures to consider |
349 | + :return: Sequence of `IDistroArch` instances. |
350 | + """ |
351 | + associated_proc_families = [ |
352 | + archivearch.processorfamily for archivearch |
353 | + in getUtility(IArchiveArchSet).getByArchive(self.archive)] |
354 | + # Return all distroarches with unrestricted processor families or with |
355 | + # processor families the archive is explicitly associated with. |
356 | + return [distroarch for distroarch in available_archs |
357 | + if not distroarch.processorfamily.restricted or |
358 | + distroarch.processorfamily in associated_proc_families] |
359 | + |
360 | def createMissingBuilds(self, architectures_available=None, |
361 | pas_verify=None, logger=None): |
362 | """See `ISourcePackagePublishingHistory`.""" |
363 | @@ -515,6 +532,9 @@ |
364 | architectures_available = list( |
365 | self.distroseries.enabled_architectures) |
366 | |
367 | + architectures_available = self._getAllowedArchitectures( |
368 | + architectures_available) |
369 | + |
370 | build_architectures = determineArchitecturesToBuild( |
371 | self, architectures_available, self.distroseries, pas_verify) |
372 | |
373 | |
374 | === modified file 'lib/lp/soyuz/tests/test_archive.py' |
375 | --- lib/lp/soyuz/tests/test_archive.py 2010-02-08 16:33:12 +0000 |
376 | +++ lib/lp/soyuz/tests/test_archive.py 2010-02-26 23:30:37 +0000 |
377 | @@ -19,8 +19,10 @@ |
378 | from lp.registry.interfaces.person import IPersonSet |
379 | from lp.services.job.interfaces.job import JobStatus |
380 | from lp.soyuz.interfaces.archive import IArchiveSet, ArchivePurpose |
381 | +from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
382 | from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat |
383 | from lp.soyuz.interfaces.build import BuildStatus |
384 | +from lp.soyuz.interfaces.processor import IProcessorFamilySet |
385 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
386 | from lp.soyuz.model.build import Build |
387 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
388 | @@ -558,5 +560,56 @@ |
389 | self.assertEqual(1, len(pubs)) |
390 | self.assertEqual('0.5.11~ppa1', pubs[0].source_package_version) |
391 | |
392 | + |
393 | +class TestARMBuildsAllowed(TestCaseWithFactory): |
394 | + """Ensure that ARM builds can be allowed and disallowed correctly.""" |
395 | + |
396 | + layer = LaunchpadZopelessLayer |
397 | + |
398 | + def setUp(self): |
399 | + """Setup an archive with relevant publications.""" |
400 | + super(TestARMBuildsAllowed, self).setUp() |
401 | + self.publisher = SoyuzTestPublisher() |
402 | + self.publisher.prepareBreezyAutotest() |
403 | + self.archive = self.factory.makeArchive() |
404 | + self.archive_arch_set = getUtility(IArchiveArchSet) |
405 | + self.arm = getUtility(IProcessorFamilySet).getByName('arm') |
406 | + |
407 | + def test_default(self): |
408 | + """By default, ARM builds are not allowed.""" |
409 | + self.assertEquals(0, |
410 | + self.archive_arch_set.getByArchive(self.archive, self.arm).count()) |
411 | + self.assertFalse(self.archive.arm_builds_allowed) |
412 | + |
413 | + def test_get_uses_archivearch(self): |
414 | + """Adding an entry to ArchiveArch for ARM and an archive will |
415 | + enable arm_builds_allowed for that archive.""" |
416 | + self.assertFalse(self.archive.arm_builds_allowed) |
417 | + self.archive_arch_set.new(self.archive, self.arm) |
418 | + self.assertTrue(self.archive.arm_builds_allowed) |
419 | + |
420 | + def test_get_uses_arm_only(self): |
421 | + """Adding an entry to ArchiveArch for something other than ARM |
422 | + does not enable arm_builds_allowed for that archive.""" |
423 | + self.assertFalse(self.archive.arm_builds_allowed) |
424 | + self.archive_arch_set.new(self.archive, |
425 | + getUtility(IProcessorFamilySet).getByName('amd64')) |
426 | + self.assertFalse(self.archive.arm_builds_allowed) |
427 | + |
428 | + def test_set(self): |
429 | + """The property remembers its value correctly and sets ArchiveArch.""" |
430 | + self.archive.arm_builds_allowed = True |
431 | + allowed_restricted_families = self.archive_arch_set.getByArchive( |
432 | + self.archive, self.arm) |
433 | + self.assertEquals(1, allowed_restricted_families.count()) |
434 | + self.assertEquals(self.arm, |
435 | + allowed_restricted_families[0].processorfamily) |
436 | + self.assertTrue(self.archive.arm_builds_allowed) |
437 | + self.archive.arm_builds_allowed = False |
438 | + self.assertEquals(0, |
439 | + self.archive_arch_set.getByArchive(self.archive, self.arm).count()) |
440 | + self.assertFalse(self.archive.arm_builds_allowed) |
441 | + |
442 | + |
443 | def test_suite(): |
444 | return unittest.TestLoader().loadTestsFromName(__name__) |
445 | |
446 | === added file 'lib/lp/soyuz/tests/test_archivearch.py' |
447 | --- lib/lp/soyuz/tests/test_archivearch.py 1970-01-01 00:00:00 +0000 |
448 | +++ lib/lp/soyuz/tests/test_archivearch.py 2010-02-26 23:30:37 +0000 |
449 | @@ -0,0 +1,57 @@ |
450 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
451 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
452 | + |
453 | +"""Test ArchiveArch features.""" |
454 | + |
455 | +import unittest |
456 | + |
457 | +from zope.component import getUtility |
458 | + |
459 | +from canonical.testing import LaunchpadZopelessLayer |
460 | + |
461 | +from lp.testing import TestCaseWithFactory |
462 | + |
463 | +from lp.registry.interfaces.person import IPersonSet |
464 | +from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
465 | +from lp.soyuz.interfaces.processor import IProcessorFamilySet |
466 | + |
467 | +class TestArchiveArch(TestCaseWithFactory): |
468 | + |
469 | + layer = LaunchpadZopelessLayer |
470 | + |
471 | + def setUp(self): |
472 | + """Use `SoyuzTestPublisher` to publish some sources in archives.""" |
473 | + super(TestArchiveArch, self).setUp() |
474 | + |
475 | + self.ppa = getUtility(IPersonSet).getByName('cprov').archive |
476 | + pss = getUtility(IProcessorFamilySet) |
477 | + self.cell_proc = pss.new( |
478 | + 'cell-proc', 'PS cell processor', 'Screamingly faaaaaaaaaaaast', |
479 | + True) |
480 | + self.omap = pss.new( |
481 | + 'omap', 'Multimedia applications processor', |
482 | + 'Does all your sound & video', True) |
483 | + |
484 | + def test_no_associations(self): |
485 | + """Our archive is not associated with any restricted processor |
486 | + families yet.""" |
487 | + result_set = list( |
488 | + getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa)) |
489 | + archivearches = [row[1] for row in result_set] |
490 | + self.assertTrue(all(aa is None for aa in archivearches)) |
491 | + |
492 | + def test_single_association(self): |
493 | + """Our archive is now associated with one of the restricted processor |
494 | + families.""" |
495 | + getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc) |
496 | + result_set = list( |
497 | + getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa)) |
498 | + results = dict( |
499 | + (row[0].name, row[1] is not None) for row in result_set) |
500 | + self.assertEquals( |
501 | + { 'arm' : False, 'cell-proc' : True, 'omap' : False}, |
502 | + results) |
503 | + |
504 | + |
505 | +def test_suite(): |
506 | + return unittest.TestLoader().loadTestsFromName(__name__) |
507 | |
508 | === added file 'lib/lp/soyuz/tests/test_processor.py' |
509 | --- lib/lp/soyuz/tests/test_processor.py 1970-01-01 00:00:00 +0000 |
510 | +++ lib/lp/soyuz/tests/test_processor.py 2010-02-26 23:30:37 +0000 |
511 | @@ -0,0 +1,32 @@ |
512 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
513 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
514 | + |
515 | +"""Test Processor and ProcessorFamily features.""" |
516 | + |
517 | +from zope.component import getUtility |
518 | + |
519 | +from canonical.testing import LaunchpadZopelessLayer |
520 | + |
521 | +from lp.soyuz.interfaces.processor import (IProcessor, IProcessorFamily, |
522 | + IProcessorFamilySet) |
523 | +from lp.testing import TestCaseWithFactory |
524 | + |
525 | + |
526 | +class ProcessorFamilyTests(TestCaseWithFactory): |
527 | + """Test ProcessorFamily.""" |
528 | + |
529 | + layer = LaunchpadZopelessLayer |
530 | + |
531 | + def test_create(self): |
532 | + """Test adding a new ProcessorFamily.""" |
533 | + family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR", |
534 | + "The Modified Harvard architecture 8-bit RISC processors.") |
535 | + self.assertProvides(family, IProcessorFamily) |
536 | + |
537 | + def test_add_processor(self): |
538 | + """Test adding a new Processor to a ProcessorFamily.""" |
539 | + family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR", |
540 | + "The Modified Harvard architecture 8-bit RISC processors.") |
541 | + proc = family.addProcessor("avr2001", "The 2001 AVR", "Fast as light.") |
542 | + self.assertProvides(proc, IProcessor) |
543 | + self.assertEquals(family, proc.family) |
544 | |
545 | === modified file 'lib/lp/soyuz/tests/test_publishing.py' |
546 | --- lib/lp/soyuz/tests/test_publishing.py 2010-02-24 10:18:16 +0000 |
547 | +++ lib/lp/soyuz/tests/test_publishing.py 2010-02-26 23:30:37 +0000 |
548 | @@ -31,6 +31,7 @@ |
549 | from lp.registry.interfaces.sourcepackage import SourcePackageUrgency |
550 | from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet |
551 | from lp.soyuz.interfaces.archive import ArchivePurpose |
552 | +from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
553 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
554 | from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat |
555 | from lp.soyuz.interfaces.build import BuildStatus |
556 | @@ -861,6 +862,104 @@ |
557 | binary, binary.distroarchseries.distroseries, 'universe') |
558 | |
559 | |
560 | +class BuildRecordCreationTests(TestNativePublishingBase): |
561 | + """Test the creation of build records.""" |
562 | + |
563 | + def setUp(self): |
564 | + super(BuildRecordCreationTests, self).setUp() |
565 | + self.distro = self.factory.makeDistribution() |
566 | + self.distroseries = self.factory.makeDistroSeries( |
567 | + distribution=self.distro, name="crazy") |
568 | + self.archive = self.factory.makeArchive() |
569 | + self.avr_family = self.factory.makeProcessorFamily( |
570 | + name="avr", restricted=True) |
571 | + self.factory.makeProcessor(self.avr_family, "avr2001") |
572 | + self.avr_distroarch = self.factory.makeDistroArchSeries( |
573 | + architecturetag='avr', processorfamily=self.avr_family, |
574 | + distroseries=self.distroseries, supports_virtualized=True) |
575 | + self.sparc_family = self.factory.makeProcessorFamily(name="sparc", |
576 | + restricted=False) |
577 | + self.factory.makeProcessor(self.sparc_family, "sparc64") |
578 | + self.sparc_distroarch = self.factory.makeDistroArchSeries( |
579 | + architecturetag='sparc', processorfamily=self.sparc_family, |
580 | + distroseries=self.distroseries, supports_virtualized=True) |
581 | + self.distroseries.nominatedarchindep = self.sparc_distroarch |
582 | + self.addFakeChroots(self.distroseries) |
583 | + |
584 | + def getPubSource(self, architecturehintlist): |
585 | + """Return a mock source package publishing record for the archive |
586 | + and architecture used in this testcase. |
587 | + |
588 | + :param architecturehintlist: Architecture hint list (e.g. "i386 amd64") |
589 | + """ |
590 | + return super(BuildRecordCreationTests, self).getPubSource( |
591 | + archive=self.archive, distroseries=self.distroseries, |
592 | + architecturehintlist=architecturehintlist) |
593 | + |
594 | + def test__getAllowedArchitectures_restricted(self): |
595 | + """Test _getAllowedArchitectures doesn't return unrestricted |
596 | + archs. |
597 | + |
598 | + For a normal archive, only unrestricted architectures should |
599 | + be used. |
600 | + """ |
601 | + available_archs = [self.sparc_distroarch, self.avr_distroarch] |
602 | + pubrec = self.getPubSource(architecturehintlist='any') |
603 | + self.assertEquals([self.sparc_distroarch], |
604 | + pubrec._getAllowedArchitectures(available_archs)) |
605 | + |
606 | + def test__getAllowedArchitectures_restricted_override(self): |
607 | + """Test _getAllowedArchitectures honors overrides of restricted archs. |
608 | + |
609 | + Restricted architectures should only be allowed if there is |
610 | + an explicit ArchiveArch association with the archive. |
611 | + """ |
612 | + available_archs = [self.sparc_distroarch, self.avr_distroarch] |
613 | + getUtility(IArchiveArchSet).new(self.archive, self.avr_family) |
614 | + pubrec = self.getPubSource(architecturehintlist='any') |
615 | + self.assertEquals([self.sparc_distroarch, self.avr_distroarch], |
616 | + pubrec._getAllowedArchitectures(available_archs)) |
617 | + |
618 | + def test_createMissingBuilds_restricts_any(self): |
619 | + """createMissingBuilds() should limit builds targeted at 'any' |
620 | + architecture to those allowed for the archive. |
621 | + """ |
622 | + pubrec = self.getPubSource(architecturehintlist='any') |
623 | + builds = pubrec.createMissingBuilds() |
624 | + self.assertEquals(1, len(builds)) |
625 | + self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries) |
626 | + |
627 | + def test_createMissingBuilds_restricts_explicitlist(self): |
628 | + """createMissingBuilds() should limit builds targeted at a |
629 | + variety of architectures architecture to those allowed for the archive. |
630 | + """ |
631 | + pubrec = self.getPubSource(architecturehintlist='sparc i386 avr') |
632 | + builds = pubrec.createMissingBuilds() |
633 | + self.assertEquals(1, len(builds)) |
634 | + self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries) |
635 | + |
636 | + def test_createMissingBuilds_restricts_all(self): |
637 | + """createMissingBuilds() should limit builds targeted at 'all' |
638 | + architectures to the nominated independent architecture, |
639 | + if that is allowed for the archive. |
640 | + """ |
641 | + pubrec = self.getPubSource(architecturehintlist='all') |
642 | + builds = pubrec.createMissingBuilds() |
643 | + self.assertEquals(1, len(builds)) |
644 | + self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries) |
645 | + |
646 | + def test_createMissingBuilds_restrict_override(self): |
647 | + """createMissingBuilds() should limit builds targeted at 'any' |
648 | + architecture to architectures that are unrestricted or |
649 | + explicitly associated with the archive. |
650 | + """ |
651 | + getUtility(IArchiveArchSet).new(self.archive, self.avr_family) |
652 | + pubrec = self.getPubSource(architecturehintlist='any') |
653 | + builds = pubrec.createMissingBuilds() |
654 | + self.assertEquals(2, len(builds)) |
655 | + self.assertEquals(self.avr_distroarch, builds[0].distroarchseries) |
656 | + self.assertEquals(self.sparc_distroarch, builds[1].distroarchseries) |
657 | + |
658 | |
659 | def test_suite(): |
660 | return unittest.TestLoader().loadTestsFromName(__name__) |
661 | |
662 | === modified file 'lib/lp/testing/factory.py' |
663 | --- lib/lp/testing/factory.py 2010-02-25 07:42:32 +0000 |
664 | +++ lib/lp/testing/factory.py 2010-02-26 23:30:37 +0000 |
665 | @@ -126,6 +126,7 @@ |
666 | from lp.soyuz.adapters.packagelocation import PackageLocation |
667 | from lp.soyuz.interfaces.component import IComponentSet |
668 | from lp.soyuz.interfaces.packageset import IPackagesetSet |
669 | +from lp.soyuz.interfaces.processor import IProcessorFamilySet |
670 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
671 | from lp.soyuz.interfaces.section import ISectionSet |
672 | from lp.soyuz.model.buildqueue import BuildQueue |
673 | @@ -613,6 +614,38 @@ |
674 | productseries=productseries, |
675 | name=name) |
676 | |
677 | + def makeProcessor(self, family, name, title=None, description=None): |
678 | + """Create a new processor. |
679 | + |
680 | + :param family: Family of the processor |
681 | + :param name: Name of the processor |
682 | + :param title: Optional title |
683 | + :param description: Optional description |
684 | + :return: A `IProcessor` |
685 | + """ |
686 | + if title is None: |
687 | + title = "The %s processor" % name |
688 | + if description is None: |
689 | + description = "The %s and processor and compatible processors" |
690 | + return family.addProcessor(name, title, description) |
691 | + |
692 | + def makeProcessorFamily(self, name, title=None, description=None, |
693 | + restricted=False): |
694 | + """Create a new processor family. |
695 | + |
696 | + :param name: Name of the family (e.g. x86) |
697 | + :param title: Optional title of the family |
698 | + :param description: Optional extended description |
699 | + :param restricted: Whether the processor family is restricted |
700 | + :return: A `IProcessorFamily` |
701 | + """ |
702 | + if description is None: |
703 | + description = "Description of the %s processor family" % name |
704 | + if title is None: |
705 | + title = "%s and compatible processors." % name |
706 | + return getUtility(IProcessorFamilySet).new(name, title, description, |
707 | + restricted=restricted) |
708 | + |
709 | def makeProductRelease(self, milestone=None, product=None, |
710 | productseries=None): |
711 | if milestone is None: |
This makes it possible for processor families to be marked restricted. Source packages in archives will only be built using these processor families if they are explicitly permitted, using an entry in ArchiveArch.
This patch also adds some infrastructure to create processor families and processors, which we use for testing.
I reran "make newsampledata" which doesn't appear to have happened in a while, so there are some updates there related to earlier branches as well.