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
=== modified file 'lib/lp/soyuz/browser/archive.py'
--- lib/lp/soyuz/browser/archive.py 2010-06-24 18:52:56 +0000
+++ lib/lp/soyuz/browser/archive.py 2010-06-30 08:49:29 +0000
@@ -78,6 +78,7 @@
78from lp.soyuz.interfaces.packageset import IPackagesetSet78from lp.soyuz.interfaces.packageset import IPackagesetSet
79from lp.registry.interfaces.person import IPersonSet, PersonVisibility79from lp.registry.interfaces.person import IPersonSet, PersonVisibility
80from lp.registry.interfaces.pocket import PackagePublishingPocket80from lp.registry.interfaces.pocket import PackagePublishingPocket
81from lp.soyuz.interfaces.processor import IProcessorFamilySet
81from lp.soyuz.interfaces.publishing import (82from lp.soyuz.interfaces.publishing import (
82 active_publishing_status, inactive_publishing_status, IPublishingSet,83 active_publishing_status, inactive_publishing_status, IPublishingSet,
83 PackagePublishingStatus)84 PackagePublishingStatus)
@@ -1874,10 +1875,12 @@
18741875
1875 field_names = ['enabled', 'private', 'require_virtualized',1876 field_names = ['enabled', 'private', 'require_virtualized',
1876 'buildd_secret', 'authorized_size', 'relative_build_score',1877 'buildd_secret', 'authorized_size', 'relative_build_score',
1877 'external_dependencies', 'arm_builds_allowed']1878 'external_dependencies']
18781879
1879 custom_widget('external_dependencies', TextAreaWidget, height=3)1880 custom_widget('external_dependencies', TextAreaWidget, height=3)
18801881
1882 custom_widget('enabled_restricted_families', LabeledMultiCheckBoxWidget)
1883
1881 def validate_save(self, action, data):1884 def validate_save(self, action, data):
1882 """Validate the save action on ArchiveAdminView.1885 """Validate the save action on ArchiveAdminView.
18831886
@@ -1951,6 +1954,31 @@
1951 """1954 """
1952 return self.context.owner.visibility == PersonVisibility.PRIVATE1955 return self.context.owner.visibility == PersonVisibility.PRIVATE
19531956
1957 def setUpFields(self):
1958 """Override `LaunchpadEditFormView`.
1959
1960 See `createEnabledRestrictedFamilies` method.
1961 """
1962 super(ArchiveAdminView, self).setUpFields()
1963 self.form_fields += self.createEnabledRestrictedFamilies()
1964
1965 def createEnabledRestrictedFamilies(self):
1966 """Creates the 'enabled_restricted_families' field.
1967
1968 """
1969 terms = []
1970 for family in getUtility(IProcessorFamilySet).getRestricted():
1971 terms.append(SimpleTerm(
1972 family, token=family.name, title=family.title))
1973 return form.Fields(
1974 List(__name__='enabled_restricted_families',
1975 title=_('Enabled restricted families'),
1976 value_type=Choice(vocabulary=SimpleVocabulary(terms)),
1977 required=False,
1978 description=_('Select the restricted architecture families '
1979 'on which this archive is allowed to build.')),
1980 render_context=self.render_context)
1981
19541982
1955class ArchiveDeleteView(LaunchpadFormView):1983class ArchiveDeleteView(LaunchpadFormView):
1956 """View class for deleting `IArchive`s"""1984 """View class for deleting `IArchive`s"""
19571985
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml 2010-06-14 11:40:34 +0000
+++ lib/lp/soyuz/configure.zcml 2010-06-30 08:49:29 +0000
@@ -405,7 +405,8 @@
405 set_attributes="description displayname publish status"/>405 set_attributes="description displayname publish status"/>
406 <require406 <require
407 permission="launchpad.Commercial"407 permission="launchpad.Commercial"
408 set_attributes="authorized_size buildd_secret arm_builds_allowed408 set_attributes="authorized_size buildd_secret
409 enabled_restricted_families
409 external_dependencies private410 external_dependencies private
410 require_virtualized relative_build_score "/>411 require_virtualized relative_build_score "/>
411 <require412 <require
412413
=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py 2010-06-24 18:52:56 +0000
+++ lib/lp/soyuz/interfaces/archive.py 2010-06-30 08:49:29 +0000
@@ -56,6 +56,7 @@
56from canonical.launchpad.interfaces.launchpad import IPrivacy56from canonical.launchpad.interfaces.launchpad import IPrivacy
57from lp.registry.interfaces.role import IHasOwner57from lp.registry.interfaces.role import IHasOwner
58from lp.soyuz.interfaces.buildrecords import IHasBuildRecords58from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
59from lp.soyuz.interfaces.processor import IProcessorFamily
59from lp.registry.interfaces.gpg import IGPGKey60from lp.registry.interfaces.gpg import IGPGKey
60from lp.registry.interfaces.person import IPerson61from lp.registry.interfaces.person import IPerson
61from canonical.launchpad.validators.name import name_validator62from canonical.launchpad.validators.name import name_validator
@@ -368,8 +369,11 @@
368 "context build.\n"369 "context build.\n"
369 "NOTE: This is for migration of OEM PPAs only!"))370 "NOTE: This is for migration of OEM PPAs only!"))
370371
371 arm_builds_allowed = Bool(372 enabled_restricted_families = CollectionField(
372 title=_("Allow ARM builds for this archive"))373 title=_("Restricted architecture families this archive can build "
374 "on"),
375 value_type=Reference(schema=IProcessorFamily),
376 readonly=False)
373377
374 def getSourcesForDeletion(name=None, status=None, distroseries=None):378 def getSourcesForDeletion(name=None, status=None, distroseries=None):
375 """All `ISourcePackagePublishingHistory` available for deletion.379 """All `ISourcePackagePublishingHistory` available for deletion.
376380
=== modified file 'lib/lp/soyuz/interfaces/processor.py'
--- lib/lp/soyuz/interfaces/processor.py 2010-02-24 15:13:10 +0000
+++ lib/lp/soyuz/interfaces/processor.py 2010-06-30 08:49:29 +0000
@@ -55,6 +55,12 @@
55 :return: A `IProcessorFamily` instance if found, None otherwise.55 :return: A `IProcessorFamily` instance if found, None otherwise.
56 """56 """
5757
58 def getRestricted():
59 """Return a sequence of all restricted architectures.
60
61 :return: A sequence of `IProcessorFamily` instances.
62 """
63
58 def getByProcessorName(name):64 def getByProcessorName(name):
59 """Given a processor name return the ProcessorFamily it belongs to.65 """Given a processor name return the ProcessorFamily it belongs to.
6066
6167
=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py 2010-06-28 14:41:21 +0000
+++ lib/lp/soyuz/model/archive.py 2010-06-30 08:49:29 +0000
@@ -211,39 +211,6 @@
211 external_dependencies = StringCol(211 external_dependencies = StringCol(
212 dbName='external_dependencies', notNull=False, default=None)212 dbName='external_dependencies', notNull=False, default=None)
213213
214 def _get_arm_builds_enabled(self):
215 """Check whether ARM builds are allowed for this archive."""
216 archive_arch_set = getUtility(IArchiveArchSet)
217 restricted_families = archive_arch_set.getRestrictedfamilies(self)
218 arm = getUtility(IProcessorFamilySet).getByName('arm')
219 for (family, archive_arch) in restricted_families:
220 if family == arm:
221 return (archive_arch is not None)
222 # ARM doesn't exist or isn't restricted. Either way, there is no
223 # need for an explicit association.
224 return False
225
226 def _set_arm_builds_enabled(self, value):
227 """Set whether ARM builds are enabled for this archive."""
228 archive_arch_set = getUtility(IArchiveArchSet)
229 restricted_families = archive_arch_set.getRestrictedfamilies(self)
230 arm = getUtility(IProcessorFamilySet).getByName('arm')
231 for (family, archive_arch) in restricted_families:
232 if family == arm:
233 if value:
234 if archive_arch is not None:
235 # ARM builds are already enabled
236 return
237 else:
238 archive_arch_set.new(self, family)
239 else:
240 if archive_arch is not None:
241 Store.of(self).remove(archive_arch)
242 else:
243 pass # ARM builds are already disabled
244 arm_builds_allowed = property(_get_arm_builds_enabled,
245 _set_arm_builds_enabled)
246
247 def _init(self, *args, **kw):214 def _init(self, *args, **kw):
248 """Provide the right interface for URL traversal."""215 """Provide the right interface for URL traversal."""
249 SQLBase._init(self, *args, **kw)216 SQLBase._init(self, *args, **kw)
@@ -1587,6 +1554,24 @@
1587 LibraryFileContent.id == LibraryFileAlias.contentID).config(1554 LibraryFileContent.id == LibraryFileAlias.contentID).config(
1588 distinct=True))1555 distinct=True))
15891556
1557 def _get_enabled_restricted_families(self):
1558 archive_arch_set = getUtility(IArchiveArchSet)
1559 restricted_families = archive_arch_set.getRestrictedfamilies(self)
1560 return [family for (family, archive_arch) in restricted_families
1561 if archive_arch is not None]
1562
1563 def _set_enabled_restricted_families(self, value):
1564 archive_arch_set = getUtility(IArchiveArchSet)
1565 restricted_families = archive_arch_set.getRestrictedfamilies(self)
1566 for (family, archive_arch) in restricted_families:
1567 if family in value and archive_arch is None:
1568 archive_arch_set.new(self, family)
1569 if family not in value and archive_arch is not None:
1570 Store.of(self).remove(archive_arch)
1571
1572 enabled_restricted_families = property(_get_enabled_restricted_families,
1573 _set_enabled_restricted_families)
1574
15901575
1591class ArchiveSet:1576class ArchiveSet:
1592 implements(IArchiveSet)1577 implements(IArchiveSet)
15931578
=== modified file 'lib/lp/soyuz/model/processor.py'
--- lib/lp/soyuz/model/processor.py 2010-02-24 16:14:37 +0000
+++ lib/lp/soyuz/model/processor.py 2010-06-30 08:49:29 +0000
@@ -59,6 +59,11 @@
59 rset = store.find(ProcessorFamily, ProcessorFamily.name == name)59 rset = store.find(ProcessorFamily, ProcessorFamily.name == name)
60 return rset.one()60 return rset.one()
6161
62 def getRestricted(self):
63 """See `IProcessorFamilySet`."""
64 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
65 return store.find(ProcessorFamily, ProcessorFamily.restricted == True)
66
62 def getByProcessorName(self, name):67 def getByProcessorName(self, name):
63 """Please see `IProcessorFamilySet`."""68 """Please see `IProcessorFamilySet`."""
64 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)69 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
6570
=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py 2010-06-18 09:35:58 +0000
+++ lib/lp/soyuz/tests/test_archive.py 2010-06-30 08:49:29 +0000
@@ -738,14 +738,15 @@
738 self.assertCount(3, self.archive, self.bpr_2, day, self.australia)738 self.assertCount(3, self.archive, self.bpr_2, day, self.australia)
739739
740740
741class TestARMBuildsAllowed(TestCaseWithFactory):741class TestEnabledRestrictedBuilds(TestCaseWithFactory):
742 """Ensure that ARM builds can be allowed and disallowed correctly."""742 """Ensure that restricted architecture family builds can be allowed and
743 disallowed correctly."""
743744
744 layer = LaunchpadZopelessLayer745 layer = LaunchpadZopelessLayer
745746
746 def setUp(self):747 def setUp(self):
747 """Setup an archive with relevant publications."""748 """Setup an archive with relevant publications."""
748 super(TestARMBuildsAllowed, self).setUp()749 super(TestEnabledRestrictedBuilds, self).setUp()
749 self.publisher = SoyuzTestPublisher()750 self.publisher = SoyuzTestPublisher()
750 self.publisher.prepareBreezyAutotest()751 self.publisher.prepareBreezyAutotest()
751 self.archive = self.factory.makeArchive()752 self.archive = self.factory.makeArchive()
@@ -753,41 +754,44 @@
753 self.arm = getUtility(IProcessorFamilySet).getByName('arm')754 self.arm = getUtility(IProcessorFamilySet).getByName('arm')
754755
755 def test_default(self):756 def test_default(self):
756 """By default, ARM builds are not allowed."""757 """By default, ARM builds are not allowed as ARM is restricted."""
757 self.assertEquals(0,758 self.assertEquals(0,
758 self.archive_arch_set.getByArchive(759 self.archive_arch_set.getByArchive(
759 self.archive, self.arm).count())760 self.archive, self.arm).count())
760 self.assertFalse(self.archive.arm_builds_allowed)761 self.assertEquals([], list(self.archive.enabled_restricted_families))
761762
762 def test_get_uses_archivearch(self):763 def test_get_uses_archivearch(self):
763 """Adding an entry to ArchiveArch for ARM and an archive will764 """Adding an entry to ArchiveArch for ARM and an archive will
764 enable arm_builds_allowed for that archive."""765 enable enabled_restricted_families for arm for that archive."""
765 self.assertFalse(self.archive.arm_builds_allowed)766 self.assertEquals([], list(self.archive.enabled_restricted_families))
766 self.archive_arch_set.new(self.archive, self.arm)767 self.archive_arch_set.new(self.archive, self.arm)
767 self.assertTrue(self.archive.arm_builds_allowed)768 self.assertEquals([self.arm],
769 list(self.archive.enabled_restricted_families))
768770
769 def test_get_uses_arm_only(self):771 def test_get_returns_restricted_only(self):
770 """Adding an entry to ArchiveArch for something other than ARM772 """Adding an entry to ArchiveArch for something that is not
771 does not enable arm_builds_allowed for that archive."""773 restricted does not make it show up in enabled_restricted_families.
772 self.assertFalse(self.archive.arm_builds_allowed)774 """
775 self.assertEquals([], list(self.archive.enabled_restricted_families))
773 self.archive_arch_set.new(self.archive,776 self.archive_arch_set.new(self.archive,
774 getUtility(IProcessorFamilySet).getByName('amd64'))777 getUtility(IProcessorFamilySet).getByName('amd64'))
775 self.assertFalse(self.archive.arm_builds_allowed)778 self.assertEquals([], list(self.archive.enabled_restricted_families))
776779
777 def test_set(self):780 def test_set(self):
778 """The property remembers its value correctly and sets ArchiveArch."""781 """The property remembers its value correctly and sets ArchiveArch."""
779 self.archive.arm_builds_allowed = True782 self.archive.enabled_restricted_families = [self.arm]
780 allowed_restricted_families = self.archive_arch_set.getByArchive(783 allowed_restricted_families = self.archive_arch_set.getByArchive(
781 self.archive, self.arm)784 self.archive, self.arm)
782 self.assertEquals(1, allowed_restricted_families.count())785 self.assertEquals(1, allowed_restricted_families.count())
783 self.assertEquals(self.arm,786 self.assertEquals(self.arm,
784 allowed_restricted_families[0].processorfamily)787 allowed_restricted_families[0].processorfamily)
785 self.assertTrue(self.archive.arm_builds_allowed)788 self.assertEquals([self.arm], self.archive.enabled_restricted_families)
786 self.archive.arm_builds_allowed = False789 self.archive.enabled_restricted_families = []
787 self.assertEquals(0,790 self.assertEquals(0,
788 self.archive_arch_set.getByArchive(791 self.archive_arch_set.getByArchive(
789 self.archive, self.arm).count())792 self.archive, self.arm).count())
790 self.assertFalse(self.archive.arm_builds_allowed)793 self.assertEquals([], list(self.archive.enabled_restricted_families))
794
791795
792class TestArchiveTokens(TestCaseWithFactory):796class TestArchiveTokens(TestCaseWithFactory):
793 layer = LaunchpadZopelessLayer797 layer = LaunchpadZopelessLayer
794798
=== modified file 'lib/lp/soyuz/tests/test_processor.py'
--- lib/lp/soyuz/tests/test_processor.py 2010-02-25 17:07:38 +0000
+++ lib/lp/soyuz/tests/test_processor.py 2010-06-30 08:49:29 +0000
@@ -30,3 +30,13 @@
30 proc = family.addProcessor("avr2001", "The 2001 AVR", "Fast as light.")30 proc = family.addProcessor("avr2001", "The 2001 AVR", "Fast as light.")
31 self.assertProvides(proc, IProcessor)31 self.assertProvides(proc, IProcessor)
32 self.assertEquals(family, proc.family)32 self.assertEquals(family, proc.family)
33
34 def test_get_restricted(self):
35 """Test retrieving all restricted processors."""
36 family_set = getUtility(IProcessorFamilySet)
37 normal_family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR",
38 "The Modified Harvard architecture 8-bit RISC processors.")
39 restricted_family = getUtility(IProcessorFamilySet).new("5051", "5051",
40 "Another small processor family", restricted=True)
41 self.assertFalse(normal_family in family_set.getRestricted())
42 self.assertTrue(restricted_family in family_set.getRestricted())