Merge lp:~jelmer/launchpad/594237-arm-checkbox into lp:launchpad

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merged at revision: 11078
Proposed branch: lp:~jelmer/launchpad/594237-arm-checkbox
Merge into: lp:launchpad
Diff against target: 299 lines (+97/-54)
8 files modified
lib/lp/soyuz/browser/archive.py (+29/-1)
lib/lp/soyuz/configure.zcml (+2/-1)
lib/lp/soyuz/interfaces/archive.py (+6/-2)
lib/lp/soyuz/interfaces/processor.py (+6/-0)
lib/lp/soyuz/model/archive.py (+18/-33)
lib/lp/soyuz/model/processor.py (+5/-0)
lib/lp/soyuz/tests/test_archive.py (+21/-17)
lib/lp/soyuz/tests/test_processor.py (+10/-0)
To merge this branch: bzr merge lp:~jelmer/launchpad/594237-arm-checkbox
Reviewer Review Type Date Requested Status
Leonard Richardson (community) Approve
Review via email: mp+28751@code.launchpad.net

Commit message

Use checkboxes to set the restricted architectures an archive can be built on.

Description of the change

This branch changes the archive administration page to allow changing what restricted architectures the archive can build on. Previously it only allowed enabling restricted ARM builds but there was a bug in the way this was implemented (https://bugs.edge.launchpad.net/soyuz/+bug/594237), while supporting the ability to toggle building on other restricted architectures was always a goal anyway (https://bugs.edge.launchpad.net/soyuz/+bug/531302).

I've added a ProcessorFamilySet.getRestricted() call which will return all restricted architecture families. This is for useful as the vocabulary of the checkboxes.

The existing tests for arm_builds_enabled have been modified to use enabled_restricted_architectures.

The result of this work can be seen on a random PPA admin page - in my case I created one for <email address hidden>:

https://launchpad.dev/~name16/+archive/ppa/+admin

Triggering the ARM checkbox results in an entry in archivearch being created:

launchpad_dev=# select * from archivearch;
 id | archive | processorfamily
----+---------+-----------------
  3 | 14 | 5
(1 row)

To post a comment you must log in.
Revision history for this message
Leonard Richardson (leonardr) wrote :

r=leonardr with changes:

1. On line 44, the arguments to SimpleTerm need to all go on their own line.

2. Don't call exported() on enable_restricted_families. The property it replaces wasn't exported to the web service, and you don't have the code that would publish IProcessorFamily objects on the web service.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/browser/archive.py'
2--- lib/lp/soyuz/browser/archive.py 2010-06-24 18:52:56 +0000
3+++ lib/lp/soyuz/browser/archive.py 2010-06-30 08:49:29 +0000
4@@ -78,6 +78,7 @@
5 from lp.soyuz.interfaces.packageset import IPackagesetSet
6 from lp.registry.interfaces.person import IPersonSet, PersonVisibility
7 from lp.registry.interfaces.pocket import PackagePublishingPocket
8+from lp.soyuz.interfaces.processor import IProcessorFamilySet
9 from lp.soyuz.interfaces.publishing import (
10 active_publishing_status, inactive_publishing_status, IPublishingSet,
11 PackagePublishingStatus)
12@@ -1874,10 +1875,12 @@
13
14 field_names = ['enabled', 'private', 'require_virtualized',
15 'buildd_secret', 'authorized_size', 'relative_build_score',
16- 'external_dependencies', 'arm_builds_allowed']
17+ 'external_dependencies']
18
19 custom_widget('external_dependencies', TextAreaWidget, height=3)
20
21+ custom_widget('enabled_restricted_families', LabeledMultiCheckBoxWidget)
22+
23 def validate_save(self, action, data):
24 """Validate the save action on ArchiveAdminView.
25
26@@ -1951,6 +1954,31 @@
27 """
28 return self.context.owner.visibility == PersonVisibility.PRIVATE
29
30+ def setUpFields(self):
31+ """Override `LaunchpadEditFormView`.
32+
33+ See `createEnabledRestrictedFamilies` method.
34+ """
35+ super(ArchiveAdminView, self).setUpFields()
36+ self.form_fields += self.createEnabledRestrictedFamilies()
37+
38+ def createEnabledRestrictedFamilies(self):
39+ """Creates the 'enabled_restricted_families' field.
40+
41+ """
42+ terms = []
43+ for family in getUtility(IProcessorFamilySet).getRestricted():
44+ terms.append(SimpleTerm(
45+ family, token=family.name, title=family.title))
46+ return form.Fields(
47+ List(__name__='enabled_restricted_families',
48+ title=_('Enabled restricted families'),
49+ value_type=Choice(vocabulary=SimpleVocabulary(terms)),
50+ required=False,
51+ description=_('Select the restricted architecture families '
52+ 'on which this archive is allowed to build.')),
53+ render_context=self.render_context)
54+
55
56 class ArchiveDeleteView(LaunchpadFormView):
57 """View class for deleting `IArchive`s"""
58
59=== modified file 'lib/lp/soyuz/configure.zcml'
60--- lib/lp/soyuz/configure.zcml 2010-06-14 11:40:34 +0000
61+++ lib/lp/soyuz/configure.zcml 2010-06-30 08:49:29 +0000
62@@ -405,7 +405,8 @@
63 set_attributes="description displayname publish status"/>
64 <require
65 permission="launchpad.Commercial"
66- set_attributes="authorized_size buildd_secret arm_builds_allowed
67+ set_attributes="authorized_size buildd_secret
68+ enabled_restricted_families
69 external_dependencies private
70 require_virtualized relative_build_score "/>
71 <require
72
73=== modified file 'lib/lp/soyuz/interfaces/archive.py'
74--- lib/lp/soyuz/interfaces/archive.py 2010-06-24 18:52:56 +0000
75+++ lib/lp/soyuz/interfaces/archive.py 2010-06-30 08:49:29 +0000
76@@ -56,6 +56,7 @@
77 from canonical.launchpad.interfaces.launchpad import IPrivacy
78 from lp.registry.interfaces.role import IHasOwner
79 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
80+from lp.soyuz.interfaces.processor import IProcessorFamily
81 from lp.registry.interfaces.gpg import IGPGKey
82 from lp.registry.interfaces.person import IPerson
83 from canonical.launchpad.validators.name import name_validator
84@@ -368,8 +369,11 @@
85 "context build.\n"
86 "NOTE: This is for migration of OEM PPAs only!"))
87
88- arm_builds_allowed = Bool(
89- title=_("Allow ARM builds for this archive"))
90+ enabled_restricted_families = CollectionField(
91+ title=_("Restricted architecture families this archive can build "
92+ "on"),
93+ value_type=Reference(schema=IProcessorFamily),
94+ readonly=False)
95
96 def getSourcesForDeletion(name=None, status=None, distroseries=None):
97 """All `ISourcePackagePublishingHistory` available for deletion.
98
99=== modified file 'lib/lp/soyuz/interfaces/processor.py'
100--- lib/lp/soyuz/interfaces/processor.py 2010-02-24 15:13:10 +0000
101+++ lib/lp/soyuz/interfaces/processor.py 2010-06-30 08:49:29 +0000
102@@ -55,6 +55,12 @@
103 :return: A `IProcessorFamily` instance if found, None otherwise.
104 """
105
106+ def getRestricted():
107+ """Return a sequence of all restricted architectures.
108+
109+ :return: A sequence of `IProcessorFamily` instances.
110+ """
111+
112 def getByProcessorName(name):
113 """Given a processor name return the ProcessorFamily it belongs to.
114
115
116=== modified file 'lib/lp/soyuz/model/archive.py'
117--- lib/lp/soyuz/model/archive.py 2010-06-28 14:41:21 +0000
118+++ lib/lp/soyuz/model/archive.py 2010-06-30 08:49:29 +0000
119@@ -211,39 +211,6 @@
120 external_dependencies = StringCol(
121 dbName='external_dependencies', notNull=False, default=None)
122
123- def _get_arm_builds_enabled(self):
124- """Check whether ARM builds are allowed for this archive."""
125- archive_arch_set = getUtility(IArchiveArchSet)
126- restricted_families = archive_arch_set.getRestrictedfamilies(self)
127- arm = getUtility(IProcessorFamilySet).getByName('arm')
128- for (family, archive_arch) in restricted_families:
129- if family == arm:
130- return (archive_arch is not None)
131- # ARM doesn't exist or isn't restricted. Either way, there is no
132- # need for an explicit association.
133- return False
134-
135- def _set_arm_builds_enabled(self, value):
136- """Set whether ARM builds are enabled for this archive."""
137- archive_arch_set = getUtility(IArchiveArchSet)
138- restricted_families = archive_arch_set.getRestrictedfamilies(self)
139- arm = getUtility(IProcessorFamilySet).getByName('arm')
140- for (family, archive_arch) in restricted_families:
141- if family == arm:
142- if value:
143- if archive_arch is not None:
144- # ARM builds are already enabled
145- return
146- else:
147- archive_arch_set.new(self, family)
148- else:
149- if archive_arch is not None:
150- Store.of(self).remove(archive_arch)
151- else:
152- pass # ARM builds are already disabled
153- arm_builds_allowed = property(_get_arm_builds_enabled,
154- _set_arm_builds_enabled)
155-
156 def _init(self, *args, **kw):
157 """Provide the right interface for URL traversal."""
158 SQLBase._init(self, *args, **kw)
159@@ -1587,6 +1554,24 @@
160 LibraryFileContent.id == LibraryFileAlias.contentID).config(
161 distinct=True))
162
163+ def _get_enabled_restricted_families(self):
164+ archive_arch_set = getUtility(IArchiveArchSet)
165+ restricted_families = archive_arch_set.getRestrictedfamilies(self)
166+ return [family for (family, archive_arch) in restricted_families
167+ if archive_arch is not None]
168+
169+ def _set_enabled_restricted_families(self, value):
170+ archive_arch_set = getUtility(IArchiveArchSet)
171+ restricted_families = archive_arch_set.getRestrictedfamilies(self)
172+ for (family, archive_arch) in restricted_families:
173+ if family in value and archive_arch is None:
174+ archive_arch_set.new(self, family)
175+ if family not in value and archive_arch is not None:
176+ Store.of(self).remove(archive_arch)
177+
178+ enabled_restricted_families = property(_get_enabled_restricted_families,
179+ _set_enabled_restricted_families)
180+
181
182 class ArchiveSet:
183 implements(IArchiveSet)
184
185=== modified file 'lib/lp/soyuz/model/processor.py'
186--- lib/lp/soyuz/model/processor.py 2010-02-24 16:14:37 +0000
187+++ lib/lp/soyuz/model/processor.py 2010-06-30 08:49:29 +0000
188@@ -59,6 +59,11 @@
189 rset = store.find(ProcessorFamily, ProcessorFamily.name == name)
190 return rset.one()
191
192+ def getRestricted(self):
193+ """See `IProcessorFamilySet`."""
194+ store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
195+ return store.find(ProcessorFamily, ProcessorFamily.restricted == True)
196+
197 def getByProcessorName(self, name):
198 """Please see `IProcessorFamilySet`."""
199 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
200
201=== modified file 'lib/lp/soyuz/tests/test_archive.py'
202--- lib/lp/soyuz/tests/test_archive.py 2010-06-18 09:35:58 +0000
203+++ lib/lp/soyuz/tests/test_archive.py 2010-06-30 08:49:29 +0000
204@@ -738,14 +738,15 @@
205 self.assertCount(3, self.archive, self.bpr_2, day, self.australia)
206
207
208-class TestARMBuildsAllowed(TestCaseWithFactory):
209- """Ensure that ARM builds can be allowed and disallowed correctly."""
210+class TestEnabledRestrictedBuilds(TestCaseWithFactory):
211+ """Ensure that restricted architecture family builds can be allowed and
212+ disallowed correctly."""
213
214 layer = LaunchpadZopelessLayer
215
216 def setUp(self):
217 """Setup an archive with relevant publications."""
218- super(TestARMBuildsAllowed, self).setUp()
219+ super(TestEnabledRestrictedBuilds, self).setUp()
220 self.publisher = SoyuzTestPublisher()
221 self.publisher.prepareBreezyAutotest()
222 self.archive = self.factory.makeArchive()
223@@ -753,41 +754,44 @@
224 self.arm = getUtility(IProcessorFamilySet).getByName('arm')
225
226 def test_default(self):
227- """By default, ARM builds are not allowed."""
228+ """By default, ARM builds are not allowed as ARM is restricted."""
229 self.assertEquals(0,
230 self.archive_arch_set.getByArchive(
231 self.archive, self.arm).count())
232- self.assertFalse(self.archive.arm_builds_allowed)
233+ self.assertEquals([], list(self.archive.enabled_restricted_families))
234
235 def test_get_uses_archivearch(self):
236 """Adding an entry to ArchiveArch for ARM and an archive will
237- enable arm_builds_allowed for that archive."""
238- self.assertFalse(self.archive.arm_builds_allowed)
239+ enable enabled_restricted_families for arm for that archive."""
240+ self.assertEquals([], list(self.archive.enabled_restricted_families))
241 self.archive_arch_set.new(self.archive, self.arm)
242- self.assertTrue(self.archive.arm_builds_allowed)
243+ self.assertEquals([self.arm],
244+ list(self.archive.enabled_restricted_families))
245
246- def test_get_uses_arm_only(self):
247- """Adding an entry to ArchiveArch for something other than ARM
248- does not enable arm_builds_allowed for that archive."""
249- self.assertFalse(self.archive.arm_builds_allowed)
250+ def test_get_returns_restricted_only(self):
251+ """Adding an entry to ArchiveArch for something that is not
252+ restricted does not make it show up in enabled_restricted_families.
253+ """
254+ self.assertEquals([], list(self.archive.enabled_restricted_families))
255 self.archive_arch_set.new(self.archive,
256 getUtility(IProcessorFamilySet).getByName('amd64'))
257- self.assertFalse(self.archive.arm_builds_allowed)
258+ self.assertEquals([], list(self.archive.enabled_restricted_families))
259
260 def test_set(self):
261 """The property remembers its value correctly and sets ArchiveArch."""
262- self.archive.arm_builds_allowed = True
263+ self.archive.enabled_restricted_families = [self.arm]
264 allowed_restricted_families = self.archive_arch_set.getByArchive(
265 self.archive, self.arm)
266 self.assertEquals(1, allowed_restricted_families.count())
267 self.assertEquals(self.arm,
268 allowed_restricted_families[0].processorfamily)
269- self.assertTrue(self.archive.arm_builds_allowed)
270- self.archive.arm_builds_allowed = False
271+ self.assertEquals([self.arm], self.archive.enabled_restricted_families)
272+ self.archive.enabled_restricted_families = []
273 self.assertEquals(0,
274 self.archive_arch_set.getByArchive(
275 self.archive, self.arm).count())
276- self.assertFalse(self.archive.arm_builds_allowed)
277+ self.assertEquals([], list(self.archive.enabled_restricted_families))
278+
279
280 class TestArchiveTokens(TestCaseWithFactory):
281 layer = LaunchpadZopelessLayer
282
283=== modified file 'lib/lp/soyuz/tests/test_processor.py'
284--- lib/lp/soyuz/tests/test_processor.py 2010-02-25 17:07:38 +0000
285+++ lib/lp/soyuz/tests/test_processor.py 2010-06-30 08:49:29 +0000
286@@ -30,3 +30,13 @@
287 proc = family.addProcessor("avr2001", "The 2001 AVR", "Fast as light.")
288 self.assertProvides(proc, IProcessor)
289 self.assertEquals(family, proc.family)
290+
291+ def test_get_restricted(self):
292+ """Test retrieving all restricted processors."""
293+ family_set = getUtility(IProcessorFamilySet)
294+ normal_family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR",
295+ "The Modified Harvard architecture 8-bit RISC processors.")
296+ restricted_family = getUtility(IProcessorFamilySet).new("5051", "5051",
297+ "Another small processor family", restricted=True)
298+ self.assertFalse(normal_family in family_set.getRestricted())
299+ self.assertTrue(restricted_family in family_set.getRestricted())