Merge lp:~jelmer/launchpad/bug471148 into lp:launchpad/db-devel

Proposed by Jelmer Vernooij
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
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.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

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.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote : Posted in a previous version of this proposal

It looks as if this diff got polluted with extraneous changes.

Revision history for this message
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/sampledata/current{,-devel}.sql to be so large - the only real
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

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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/documentation
<rockstar> lib/lp/soyuz/tests/test_processor.py and lib/lp/soyuz/tests/test_publishing.py
<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.

review: Approve (code)
Revision history for this message
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-35-0.sql.

review: Approve (db)
Revision history for this message
Björn Tillenius (bjornt) wrote :

I also would like to see a better name, but can't think of any right now.

review: Approve (db)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql 2010-02-25 08:39:19 +0000
+++ database/sampledata/current-dev.sql 2010-02-26 23:30:37 +0000
@@ -8143,10 +8143,11 @@
81438143
8144ALTER TABLE processorfamily DISABLE TRIGGER ALL;8144ALTER TABLE processorfamily DISABLE TRIGGER ALL;
81458145
8146INSERT INTO processorfamily (id, name, title, description) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!');8146INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!', false);
8147INSERT 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.');8147INSERT 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);
8148INSERT 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.');8148INSERT 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);
8149INSERT INTO processorfamily (id, name, title, description) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors');8149INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors', false);
8150INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (5, 'arm', 'ARM Processors', 'The ARM and compatible processors', true);
81508151
81518152
8152ALTER TABLE processorfamily ENABLE TRIGGER ALL;8153ALTER TABLE processorfamily ENABLE TRIGGER ALL;
81538154
=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql 2010-02-25 08:39:19 +0000
+++ database/sampledata/current.sql 2010-02-26 23:30:37 +0000
@@ -8039,10 +8039,11 @@
80398039
8040ALTER TABLE processorfamily DISABLE TRIGGER ALL;8040ALTER TABLE processorfamily DISABLE TRIGGER ALL;
80418041
8042INSERT INTO processorfamily (id, name, title, description) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!');8042INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (1, 'x86', 'Intel 386 compatible chips', 'Bring back the 8086!', false);
8043INSERT 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.');8043INSERT 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);
8044INSERT 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.');8044INSERT 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);
8045INSERT INTO processorfamily (id, name, title, description) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors');8045INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (4, 'hppa', 'PA-RISC Processors', 'The HP PA-RISC and compatible processors', false);
8046INSERT INTO processorfamily (id, name, title, description, restricted) VALUES (5, 'arm', 'ARM Processors', 'The ARM and compatible processors', true);
80468047
80478048
8048ALTER TABLE processorfamily ENABLE TRIGGER ALL;8049ALTER TABLE processorfamily ENABLE TRIGGER ALL;
80498050
=== added file 'database/schema/patch-2207-35-0.sql'
--- database/schema/patch-2207-35-0.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2207-35-0.sql 2010-02-26 23:30:37 +0000
@@ -0,0 +1,8 @@
1-- Copyright 2010 Canonical Ltd. This software is licensed under the
2-- GNU Affero General Public License version 3 (see the file LICENSE).
3
4SET client_min_messages=ERROR;
5
6ALTER TABLE processorfamily ADD COLUMN restricted boolean DEFAULT FALSE NOT NULL;
7
8INSERT INTO LaunchpadDatabaseRevision VALUES (2207, 35, 0);
09
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2010-02-22 12:44:29 +0000
+++ database/schema/security.cfg 2010-02-26 23:30:37 +0000
@@ -125,7 +125,7 @@
125public.archive = SELECT, INSERT, UPDATE125public.archive = SELECT, INSERT, UPDATE
126public.archiveauthtoken = SELECT, INSERT, UPDATE126public.archiveauthtoken = SELECT, INSERT, UPDATE
127public.archivesubscriber = SELECT, INSERT, UPDATE127public.archivesubscriber = SELECT, INSERT, UPDATE
128public.archivearch = SELECT, INSERT, UPDATE128public.archivearch = SELECT, INSERT, UPDATE, DELETE
129public.archivedependency = SELECT, INSERT, DELETE129public.archivedependency = SELECT, INSERT, DELETE
130public.archivepermission = SELECT, INSERT, UPDATE, DELETE130public.archivepermission = SELECT, INSERT, UPDATE, DELETE
131public.authtoken = SELECT, INSERT, UPDATE, DELETE131public.authtoken = SELECT, INSERT, UPDATE, DELETE
@@ -916,7 +916,7 @@
916# certain processes, such as the librarian tables. This group is deprecated -916# certain processes, such as the librarian tables. This group is deprecated -
917# access should be explicitly granted to users.917# access should be explicitly granted to users.
918public.archive = SELECT, INSERT, UPDATE918public.archive = SELECT, INSERT, UPDATE
919public.archivearch = SELECT, INSERT, UPDATE919public.archivearch = SELECT, INSERT, UPDATE, DELETE
920public.binarypackagerelease = SELECT, INSERT, UPDATE920public.binarypackagerelease = SELECT, INSERT, UPDATE
921public.binarypackagefile = SELECT, INSERT, UPDATE921public.binarypackagefile = SELECT, INSERT, UPDATE
922public.binarypackagefilepublishing = SELECT, INSERT, UPDATE922public.binarypackagefilepublishing = SELECT, INSERT, UPDATE
923923
=== modified file 'lib/lp/soyuz/browser/archive.py'
--- lib/lp/soyuz/browser/archive.py 2010-02-25 16:49:16 +0000
+++ lib/lp/soyuz/browser/archive.py 2010-02-26 23:30:37 +0000
@@ -1790,7 +1790,7 @@
17901790
1791 field_names = ['enabled', 'private', 'require_virtualized',1791 field_names = ['enabled', 'private', 'require_virtualized',
1792 'buildd_secret', 'authorized_size', 'relative_build_score',1792 'buildd_secret', 'authorized_size', 'relative_build_score',
1793 'external_dependencies']1793 'external_dependencies', 'arm_builds_allowed']
17941794
1795 custom_widget('external_dependencies', TextAreaWidget, height=3)1795 custom_widget('external_dependencies', TextAreaWidget, height=3)
17961796
17971797
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml 2010-02-25 22:41:23 +0000
+++ lib/lp/soyuz/configure.zcml 2010-02-26 23:30:37 +0000
@@ -400,7 +400,8 @@
400 <require400 <require
401 permission="launchpad.Edit"401 permission="launchpad.Edit"
402 interface="lp.soyuz.interfaces.archive.IArchiveEdit"402 interface="lp.soyuz.interfaces.archive.IArchiveEdit"
403 set_attributes="description displayname publish"/>403 set_attributes="description displayname arm_builds_allowed
404 publish"/>
404 <require405 <require
405 permission="launchpad.Commercial"406 permission="launchpad.Commercial"
406 set_attributes="authorized_size buildd_secret407 set_attributes="authorized_size buildd_secret
407408
=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py 2010-02-25 16:49:16 +0000
+++ lib/lp/soyuz/interfaces/archive.py 2010-02-26 23:30:37 +0000
@@ -1090,6 +1090,9 @@
1090 def disable():1090 def disable():
1091 """Disable the archive."""1091 """Disable the archive."""
10921092
1093 arm_builds_allowed = Bool(
1094 title=_("Allow ARM builds for this archive"))
1095
10931096
1094class IArchive(IArchivePublic, IArchiveAppend, IArchiveEdit, IArchiveView):1097class IArchive(IArchivePublic, IArchiveAppend, IArchiveEdit, IArchiveView):
1095 """Main Archive interface."""1098 """Main Archive interface."""
10961099
=== modified file 'lib/lp/soyuz/interfaces/archivearch.py'
--- lib/lp/soyuz/interfaces/archivearch.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/interfaces/archivearch.py 2010-02-26 23:30:37 +0000
@@ -62,3 +62,14 @@
6262
63 :return: A (potentially empty) result set of `IArchiveArch` instances.63 :return: A (potentially empty) result set of `IArchiveArch` instances.
64 """64 """
65
66 def getRestrictedfamilies(archive):
67 """All restricted processor families, paired with `ArchiveArch`
68 instances if associated with `archive`.
69
70 :return: A sequence containing a (`ProcessorFamily`, `ArchiveArch`)
71 2-tuple for each processor family.
72 The second value in the tuple will be None if the given `archive`
73 is not associated with the `ProcessorFamily` yet.
74 """
75
6576
=== modified file 'lib/lp/soyuz/interfaces/processor.py'
--- lib/lp/soyuz/interfaces/processor.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/interfaces/processor.py 2010-02-26 23:30:37 +0000
@@ -13,7 +13,10 @@
13 'IProcessorFamilySet',13 'IProcessorFamilySet',
14 ]14 ]
1515
16from canonical.launchpad import _
17
16from zope.interface import Interface, Attribute18from zope.interface import Interface, Attribute
19from zope.schema import Bool
1720
18class IProcessor(Interface):21class IProcessor(Interface):
19 """The SQLObject Processor Interface"""22 """The SQLObject Processor Interface"""
@@ -29,11 +32,21 @@
29 name = Attribute("The Processor Family Name")32 name = Attribute("The Processor Family Name")
30 title = Attribute("The Processor Family Title")33 title = Attribute("The Processor Family Title")
31 description = Attribute("The Processor Name Description")34 description = Attribute("The Processor Name Description")
32
33 processors = Attribute("The Processors in this family.")35 processors = Attribute("The Processors in this family.")
36 restricted = Bool(title=_("Whether this family is restricted."))
37
38 def addProcessor(name, title, description):
39 """Add a new processor to this family.
40
41 :param name: Name of the processor
42 :param title: Title of the processor
43 :param description: Description of the processor
44 :return: A `IProcessor`
45 """
3446
35class IProcessorFamilySet(Interface):47class IProcessorFamilySet(Interface):
36 """Operations related to ProcessorFamily instances."""48 """Operations related to ProcessorFamily instances."""
49
37 def getByName(name):50 def getByName(name):
38 """Return the ProcessorFamily instance with the matching name.51 """Return the ProcessorFamily instance with the matching name.
3952
@@ -49,3 +62,13 @@
4962
50 :return: A `IProcessorFamily` instance if found, None otherwise.63 :return: A `IProcessorFamily` instance if found, None otherwise.
51 """64 """
65
66 def new(name, title, description, restricted):
67 """Create a new processor family.
68
69 :param name: Name of the family.
70 :param title: Title for the family.
71 :param description: Extended description of the family
72 :param restricted: Whether the processor family is restricted
73 :return: a `IProcessorFamily`.
74 """
5275
=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py 2010-02-18 17:05:50 +0000
+++ lib/lp/soyuz/model/archive.py 2010-02-26 23:30:37 +0000
@@ -59,6 +59,7 @@
59 IDistributionArchive, InvalidComponent, IPPA, MAIN_ARCHIVE_PURPOSES,59 IDistributionArchive, InvalidComponent, IPPA, MAIN_ARCHIVE_PURPOSES,
60 NoSuchPPA, PocketNotFound, VersionRequiresName, default_name_by_purpose)60 NoSuchPPA, PocketNotFound, VersionRequiresName, default_name_by_purpose)
61from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthTokenSet61from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthTokenSet
62from lp.soyuz.interfaces.archivearch import IArchiveArchSet
62from lp.soyuz.interfaces.archivepermission import (63from lp.soyuz.interfaces.archivepermission import (
63 ArchivePermissionType, IArchivePermissionSet)64 ArchivePermissionType, IArchivePermissionSet)
64from lp.soyuz.interfaces.archivesubscriber import (65from lp.soyuz.interfaces.archivesubscriber import (
@@ -75,6 +76,7 @@
75from lp.registry.interfaces.role import IHasOwner76from lp.registry.interfaces.role import IHasOwner
76from lp.soyuz.interfaces.queue import PackageUploadStatus77from lp.soyuz.interfaces.queue import PackageUploadStatus
77from lp.soyuz.interfaces.packagecopyrequest import IPackageCopyRequestSet78from lp.soyuz.interfaces.packagecopyrequest import IPackageCopyRequestSet
79from lp.soyuz.interfaces.processor import IProcessorFamilySet
78from lp.soyuz.interfaces.publishing import (80from lp.soyuz.interfaces.publishing import (
79 active_publishing_status, PackagePublishingStatus, IPublishingSet)81 active_publishing_status, PackagePublishingStatus, IPublishingSet)
80from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet82from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
@@ -182,6 +184,39 @@
182 external_dependencies = StringCol(184 external_dependencies = StringCol(
183 dbName='external_dependencies', notNull=False, default=None)185 dbName='external_dependencies', notNull=False, default=None)
184186
187 def _get_arm_builds_enabled(self):
188 """Check whether ARM builds are allowed for this archive."""
189 archive_arch_set = getUtility(IArchiveArchSet)
190 restricted_families = archive_arch_set.getRestrictedfamilies(self)
191 arm = getUtility(IProcessorFamilySet).getByName('arm')
192 for (family, archive_arch) in restricted_families:
193 if family == arm:
194 return (archive_arch is not None)
195 # ARM doesn't exist or isn't restricted. Either way, there is no
196 # need for an explicit association.
197 return False
198
199 def _set_arm_builds_enabled(self, value):
200 """Set whether ARM builds are enabled for this archive."""
201 archive_arch_set = getUtility(IArchiveArchSet)
202 restricted_families = archive_arch_set.getRestrictedfamilies(self)
203 arm = getUtility(IProcessorFamilySet).getByName('arm')
204 for (family, archive_arch) in restricted_families:
205 if family == arm:
206 if value:
207 if archive_arch is not None:
208 # ARM builds are already enabled
209 return
210 else:
211 archive_arch_set.new(self, family)
212 else:
213 if archive_arch is not None:
214 Store.of(self).remove(archive_arch)
215 else:
216 pass # ARM builds are already disabled
217 arm_builds_allowed = property(_get_arm_builds_enabled,
218 _set_arm_builds_enabled)
219
185 def _init(self, *args, **kw):220 def _init(self, *args, **kw):
186 """Provide the right interface for URL traversal."""221 """Provide the right interface for URL traversal."""
187 SQLBase._init(self, *args, **kw)222 SQLBase._init(self, *args, **kw)
188223
=== modified file 'lib/lp/soyuz/model/archivearch.py'
--- lib/lp/soyuz/model/archivearch.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/model/archivearch.py 2010-02-26 23:30:37 +0000
@@ -9,9 +9,11 @@
99
10from lp.soyuz.interfaces.archivearch import (10from lp.soyuz.interfaces.archivearch import (
11 IArchiveArch, IArchiveArchSet)11 IArchiveArch, IArchiveArchSet)
12from lp.soyuz.model.processor import ProcessorFamily
12from canonical.launchpad.webapp.interfaces import (13from canonical.launchpad.webapp.interfaces import (
13 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)14 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
1415
16from storm.expr import Join, LeftJoin
15from storm.locals import Int, Reference, Storm17from storm.locals import Int, Reference, Storm
1618
1719
@@ -55,3 +57,17 @@
55 results = results.order_by(ArchiveArch.id)57 results = results.order_by(ArchiveArch.id)
5658
57 return results59 return results
60
61 def getRestrictedfamilies(self, archive):
62 """See `IArchiveArchSet`."""
63 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
64 origin = (
65 ProcessorFamily,
66 LeftJoin(
67 ArchiveArch,
68 ArchiveArch.processorfamily == ProcessorFamily.id))
69 result_set = store.using(*origin).find(
70 (ProcessorFamily, ArchiveArch),
71 (ProcessorFamily.restricted == True))
72
73 return result_set.order_by(ProcessorFamily.name)
5874
=== modified file 'lib/lp/soyuz/model/processor.py'
--- lib/lp/soyuz/model/processor.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/model/processor.py 2010-02-26 23:30:37 +0000
@@ -10,6 +10,7 @@
10from zope.interface import implements10from zope.interface import implements
1111
12from sqlobject import StringCol, ForeignKey, SQLMultipleJoin12from sqlobject import StringCol, ForeignKey, SQLMultipleJoin
13from storm.locals import Bool
1314
14from canonical.database.sqlbase import SQLBase15from canonical.database.sqlbase import SQLBase
1516
@@ -39,6 +40,12 @@
39 description = StringCol(dbName='description', notNull=True)40 description = StringCol(dbName='description', notNull=True)
4041
41 processors = SQLMultipleJoin('Processor', joinColumn='family')42 processors = SQLMultipleJoin('Processor', joinColumn='family')
43 restricted = Bool(allow_none=False, default=False)
44
45 def addProcessor(self, name, title, description):
46 """See `IProcessorFamily`."""
47 return Processor(family=self, name=name, title=title,
48 description=description)
4249
4350
44class ProcessorFamilySet:51class ProcessorFamilySet:
@@ -62,3 +69,8 @@
62 # but there is also the possibility that the user specified a name for69 # but there is also the possibility that the user specified a name for
63 # a non-existent processor.70 # a non-existent processor.
64 return rset.one()71 return rset.one()
72
73 def new(self, name, title, description, restricted=False):
74 """See `IProcessorFamily`."""
75 return ProcessorFamily(name=name, title=title,
76 description=description, restricted=restricted)
6577
=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py 2010-02-15 12:59:55 +0000
+++ lib/lp/soyuz/model/publishing.py 2010-02-26 23:30:37 +0000
@@ -45,14 +45,15 @@
45 LibraryFileAlias, LibraryFileContent)45 LibraryFileAlias, LibraryFileContent)
46from lp.soyuz.model.packagediff import PackageDiff46from lp.soyuz.model.packagediff import PackageDiff
47from lp.soyuz.interfaces.archive import ArchivePurpose47from lp.soyuz.interfaces.archive import ArchivePurpose
48from lp.soyuz.interfaces.archivearch import IArchiveArchSet
48from lp.soyuz.interfaces.component import IComponentSet49from lp.soyuz.interfaces.component import IComponentSet
49from lp.soyuz.interfaces.queue import PackageUploadStatus50from lp.soyuz.interfaces.queue import PackageUploadStatus
50from lp.soyuz.interfaces.publishing import (51from lp.soyuz.interfaces.publishing import (
51 active_publishing_status, IArchiveSafePublisher,52 active_publishing_status, IBinaryPackageFilePublishing,
52 IBinaryPackageFilePublishing, IBinaryPackagePublishingHistory,53 IBinaryPackagePublishingHistory, IPublishingSet,
53 IPublishingEdit, IPublishingSet, ISourcePackageFilePublishing,54 ISourcePackageFilePublishing, ISourcePackagePublishingHistory,
54 ISourcePackagePublishingHistory, PackagePublishingPriority,55 PackagePublishingPriority, PackagePublishingStatus,
55 PackagePublishingStatus, PoolFileOverwriteError)56 PoolFileOverwriteError)
56from lp.soyuz.interfaces.build import BuildSetStatus, BuildStatus, IBuildSet57from lp.soyuz.interfaces.build import BuildSetStatus, BuildStatus, IBuildSet
57from lp.soyuz.scripts.changeoverride import ArchiveOverriderError58from lp.soyuz.scripts.changeoverride import ArchiveOverriderError
58from canonical.launchpad.components.decoratedresultset import (59from canonical.launchpad.components.decoratedresultset import (
@@ -505,6 +506,22 @@
505 the_url = self._proxied_urls((changes_lfa,), self.archive)[0]506 the_url = self._proxied_urls((changes_lfa,), self.archive)[0]
506 return the_url507 return the_url
507508
509 def _getAllowedArchitectures(self, available_archs):
510 """Filter out any restricted architectures not specifically allowed
511 for an archive.
512
513 :param available_archs: Architectures to consider
514 :return: Sequence of `IDistroArch` instances.
515 """
516 associated_proc_families = [
517 archivearch.processorfamily for archivearch
518 in getUtility(IArchiveArchSet).getByArchive(self.archive)]
519 # Return all distroarches with unrestricted processor families or with
520 # processor families the archive is explicitly associated with.
521 return [distroarch for distroarch in available_archs
522 if not distroarch.processorfamily.restricted or
523 distroarch.processorfamily in associated_proc_families]
524
508 def createMissingBuilds(self, architectures_available=None,525 def createMissingBuilds(self, architectures_available=None,
509 pas_verify=None, logger=None):526 pas_verify=None, logger=None):
510 """See `ISourcePackagePublishingHistory`."""527 """See `ISourcePackagePublishingHistory`."""
@@ -515,6 +532,9 @@
515 architectures_available = list(532 architectures_available = list(
516 self.distroseries.enabled_architectures)533 self.distroseries.enabled_architectures)
517534
535 architectures_available = self._getAllowedArchitectures(
536 architectures_available)
537
518 build_architectures = determineArchitecturesToBuild(538 build_architectures = determineArchitecturesToBuild(
519 self, architectures_available, self.distroseries, pas_verify)539 self, architectures_available, self.distroseries, pas_verify)
520540
521541
=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py 2010-02-08 16:33:12 +0000
+++ lib/lp/soyuz/tests/test_archive.py 2010-02-26 23:30:37 +0000
@@ -19,8 +19,10 @@
19from lp.registry.interfaces.person import IPersonSet19from lp.registry.interfaces.person import IPersonSet
20from lp.services.job.interfaces.job import JobStatus20from lp.services.job.interfaces.job import JobStatus
21from lp.soyuz.interfaces.archive import IArchiveSet, ArchivePurpose21from lp.soyuz.interfaces.archive import IArchiveSet, ArchivePurpose
22from lp.soyuz.interfaces.archivearch import IArchiveArchSet
22from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat23from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
23from lp.soyuz.interfaces.build import BuildStatus24from lp.soyuz.interfaces.build import BuildStatus
25from lp.soyuz.interfaces.processor import IProcessorFamilySet
24from lp.soyuz.interfaces.publishing import PackagePublishingStatus26from lp.soyuz.interfaces.publishing import PackagePublishingStatus
25from lp.soyuz.model.build import Build27from lp.soyuz.model.build import Build
26from lp.soyuz.tests.test_publishing import SoyuzTestPublisher28from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
@@ -558,5 +560,56 @@
558 self.assertEqual(1, len(pubs))560 self.assertEqual(1, len(pubs))
559 self.assertEqual('0.5.11~ppa1', pubs[0].source_package_version)561 self.assertEqual('0.5.11~ppa1', pubs[0].source_package_version)
560562
563
564class TestARMBuildsAllowed(TestCaseWithFactory):
565 """Ensure that ARM builds can be allowed and disallowed correctly."""
566
567 layer = LaunchpadZopelessLayer
568
569 def setUp(self):
570 """Setup an archive with relevant publications."""
571 super(TestARMBuildsAllowed, self).setUp()
572 self.publisher = SoyuzTestPublisher()
573 self.publisher.prepareBreezyAutotest()
574 self.archive = self.factory.makeArchive()
575 self.archive_arch_set = getUtility(IArchiveArchSet)
576 self.arm = getUtility(IProcessorFamilySet).getByName('arm')
577
578 def test_default(self):
579 """By default, ARM builds are not allowed."""
580 self.assertEquals(0,
581 self.archive_arch_set.getByArchive(self.archive, self.arm).count())
582 self.assertFalse(self.archive.arm_builds_allowed)
583
584 def test_get_uses_archivearch(self):
585 """Adding an entry to ArchiveArch for ARM and an archive will
586 enable arm_builds_allowed for that archive."""
587 self.assertFalse(self.archive.arm_builds_allowed)
588 self.archive_arch_set.new(self.archive, self.arm)
589 self.assertTrue(self.archive.arm_builds_allowed)
590
591 def test_get_uses_arm_only(self):
592 """Adding an entry to ArchiveArch for something other than ARM
593 does not enable arm_builds_allowed for that archive."""
594 self.assertFalse(self.archive.arm_builds_allowed)
595 self.archive_arch_set.new(self.archive,
596 getUtility(IProcessorFamilySet).getByName('amd64'))
597 self.assertFalse(self.archive.arm_builds_allowed)
598
599 def test_set(self):
600 """The property remembers its value correctly and sets ArchiveArch."""
601 self.archive.arm_builds_allowed = True
602 allowed_restricted_families = self.archive_arch_set.getByArchive(
603 self.archive, self.arm)
604 self.assertEquals(1, allowed_restricted_families.count())
605 self.assertEquals(self.arm,
606 allowed_restricted_families[0].processorfamily)
607 self.assertTrue(self.archive.arm_builds_allowed)
608 self.archive.arm_builds_allowed = False
609 self.assertEquals(0,
610 self.archive_arch_set.getByArchive(self.archive, self.arm).count())
611 self.assertFalse(self.archive.arm_builds_allowed)
612
613
561def test_suite():614def test_suite():
562 return unittest.TestLoader().loadTestsFromName(__name__)615 return unittest.TestLoader().loadTestsFromName(__name__)
563616
=== added file 'lib/lp/soyuz/tests/test_archivearch.py'
--- lib/lp/soyuz/tests/test_archivearch.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_archivearch.py 2010-02-26 23:30:37 +0000
@@ -0,0 +1,57 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test ArchiveArch features."""
5
6import unittest
7
8from zope.component import getUtility
9
10from canonical.testing import LaunchpadZopelessLayer
11
12from lp.testing import TestCaseWithFactory
13
14from lp.registry.interfaces.person import IPersonSet
15from lp.soyuz.interfaces.archivearch import IArchiveArchSet
16from lp.soyuz.interfaces.processor import IProcessorFamilySet
17
18class TestArchiveArch(TestCaseWithFactory):
19
20 layer = LaunchpadZopelessLayer
21
22 def setUp(self):
23 """Use `SoyuzTestPublisher` to publish some sources in archives."""
24 super(TestArchiveArch, self).setUp()
25
26 self.ppa = getUtility(IPersonSet).getByName('cprov').archive
27 pss = getUtility(IProcessorFamilySet)
28 self.cell_proc = pss.new(
29 'cell-proc', 'PS cell processor', 'Screamingly faaaaaaaaaaaast',
30 True)
31 self.omap = pss.new(
32 'omap', 'Multimedia applications processor',
33 'Does all your sound & video', True)
34
35 def test_no_associations(self):
36 """Our archive is not associated with any restricted processor
37 families yet."""
38 result_set = list(
39 getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa))
40 archivearches = [row[1] for row in result_set]
41 self.assertTrue(all(aa is None for aa in archivearches))
42
43 def test_single_association(self):
44 """Our archive is now associated with one of the restricted processor
45 families."""
46 getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
47 result_set = list(
48 getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa))
49 results = dict(
50 (row[0].name, row[1] is not None) for row in result_set)
51 self.assertEquals(
52 { 'arm' : False, 'cell-proc' : True, 'omap' : False},
53 results)
54
55
56def test_suite():
57 return unittest.TestLoader().loadTestsFromName(__name__)
058
=== added file 'lib/lp/soyuz/tests/test_processor.py'
--- lib/lp/soyuz/tests/test_processor.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_processor.py 2010-02-26 23:30:37 +0000
@@ -0,0 +1,32 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test Processor and ProcessorFamily features."""
5
6from zope.component import getUtility
7
8from canonical.testing import LaunchpadZopelessLayer
9
10from lp.soyuz.interfaces.processor import (IProcessor, IProcessorFamily,
11 IProcessorFamilySet)
12from lp.testing import TestCaseWithFactory
13
14
15class ProcessorFamilyTests(TestCaseWithFactory):
16 """Test ProcessorFamily."""
17
18 layer = LaunchpadZopelessLayer
19
20 def test_create(self):
21 """Test adding a new ProcessorFamily."""
22 family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR",
23 "The Modified Harvard architecture 8-bit RISC processors.")
24 self.assertProvides(family, IProcessorFamily)
25
26 def test_add_processor(self):
27 """Test adding a new Processor to a ProcessorFamily."""
28 family = getUtility(IProcessorFamilySet).new("avr", "Atmel AVR",
29 "The Modified Harvard architecture 8-bit RISC processors.")
30 proc = family.addProcessor("avr2001", "The 2001 AVR", "Fast as light.")
31 self.assertProvides(proc, IProcessor)
32 self.assertEquals(family, proc.family)
033
=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
--- lib/lp/soyuz/tests/test_publishing.py 2010-02-24 10:18:16 +0000
+++ lib/lp/soyuz/tests/test_publishing.py 2010-02-26 23:30:37 +0000
@@ -31,6 +31,7 @@
31from lp.registry.interfaces.sourcepackage import SourcePackageUrgency31from lp.registry.interfaces.sourcepackage import SourcePackageUrgency
32from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet32from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
33from lp.soyuz.interfaces.archive import ArchivePurpose33from lp.soyuz.interfaces.archive import ArchivePurpose
34from lp.soyuz.interfaces.archivearch import IArchiveArchSet
34from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet35from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
35from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat36from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
36from lp.soyuz.interfaces.build import BuildStatus37from lp.soyuz.interfaces.build import BuildStatus
@@ -861,6 +862,104 @@
861 binary, binary.distroarchseries.distroseries, 'universe')862 binary, binary.distroarchseries.distroseries, 'universe')
862863
863864
865class BuildRecordCreationTests(TestNativePublishingBase):
866 """Test the creation of build records."""
867
868 def setUp(self):
869 super(BuildRecordCreationTests, self).setUp()
870 self.distro = self.factory.makeDistribution()
871 self.distroseries = self.factory.makeDistroSeries(
872 distribution=self.distro, name="crazy")
873 self.archive = self.factory.makeArchive()
874 self.avr_family = self.factory.makeProcessorFamily(
875 name="avr", restricted=True)
876 self.factory.makeProcessor(self.avr_family, "avr2001")
877 self.avr_distroarch = self.factory.makeDistroArchSeries(
878 architecturetag='avr', processorfamily=self.avr_family,
879 distroseries=self.distroseries, supports_virtualized=True)
880 self.sparc_family = self.factory.makeProcessorFamily(name="sparc",
881 restricted=False)
882 self.factory.makeProcessor(self.sparc_family, "sparc64")
883 self.sparc_distroarch = self.factory.makeDistroArchSeries(
884 architecturetag='sparc', processorfamily=self.sparc_family,
885 distroseries=self.distroseries, supports_virtualized=True)
886 self.distroseries.nominatedarchindep = self.sparc_distroarch
887 self.addFakeChroots(self.distroseries)
888
889 def getPubSource(self, architecturehintlist):
890 """Return a mock source package publishing record for the archive
891 and architecture used in this testcase.
892
893 :param architecturehintlist: Architecture hint list (e.g. "i386 amd64")
894 """
895 return super(BuildRecordCreationTests, self).getPubSource(
896 archive=self.archive, distroseries=self.distroseries,
897 architecturehintlist=architecturehintlist)
898
899 def test__getAllowedArchitectures_restricted(self):
900 """Test _getAllowedArchitectures doesn't return unrestricted
901 archs.
902
903 For a normal archive, only unrestricted architectures should
904 be used.
905 """
906 available_archs = [self.sparc_distroarch, self.avr_distroarch]
907 pubrec = self.getPubSource(architecturehintlist='any')
908 self.assertEquals([self.sparc_distroarch],
909 pubrec._getAllowedArchitectures(available_archs))
910
911 def test__getAllowedArchitectures_restricted_override(self):
912 """Test _getAllowedArchitectures honors overrides of restricted archs.
913
914 Restricted architectures should only be allowed if there is
915 an explicit ArchiveArch association with the archive.
916 """
917 available_archs = [self.sparc_distroarch, self.avr_distroarch]
918 getUtility(IArchiveArchSet).new(self.archive, self.avr_family)
919 pubrec = self.getPubSource(architecturehintlist='any')
920 self.assertEquals([self.sparc_distroarch, self.avr_distroarch],
921 pubrec._getAllowedArchitectures(available_archs))
922
923 def test_createMissingBuilds_restricts_any(self):
924 """createMissingBuilds() should limit builds targeted at 'any'
925 architecture to those allowed for the archive.
926 """
927 pubrec = self.getPubSource(architecturehintlist='any')
928 builds = pubrec.createMissingBuilds()
929 self.assertEquals(1, len(builds))
930 self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries)
931
932 def test_createMissingBuilds_restricts_explicitlist(self):
933 """createMissingBuilds() should limit builds targeted at a
934 variety of architectures architecture to those allowed for the archive.
935 """
936 pubrec = self.getPubSource(architecturehintlist='sparc i386 avr')
937 builds = pubrec.createMissingBuilds()
938 self.assertEquals(1, len(builds))
939 self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries)
940
941 def test_createMissingBuilds_restricts_all(self):
942 """createMissingBuilds() should limit builds targeted at 'all'
943 architectures to the nominated independent architecture,
944 if that is allowed for the archive.
945 """
946 pubrec = self.getPubSource(architecturehintlist='all')
947 builds = pubrec.createMissingBuilds()
948 self.assertEquals(1, len(builds))
949 self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries)
950
951 def test_createMissingBuilds_restrict_override(self):
952 """createMissingBuilds() should limit builds targeted at 'any'
953 architecture to architectures that are unrestricted or
954 explicitly associated with the archive.
955 """
956 getUtility(IArchiveArchSet).new(self.archive, self.avr_family)
957 pubrec = self.getPubSource(architecturehintlist='any')
958 builds = pubrec.createMissingBuilds()
959 self.assertEquals(2, len(builds))
960 self.assertEquals(self.avr_distroarch, builds[0].distroarchseries)
961 self.assertEquals(self.sparc_distroarch, builds[1].distroarchseries)
962
864963
865def test_suite():964def test_suite():
866 return unittest.TestLoader().loadTestsFromName(__name__)965 return unittest.TestLoader().loadTestsFromName(__name__)
867966
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-02-25 07:42:32 +0000
+++ lib/lp/testing/factory.py 2010-02-26 23:30:37 +0000
@@ -126,6 +126,7 @@
126from lp.soyuz.adapters.packagelocation import PackageLocation126from lp.soyuz.adapters.packagelocation import PackageLocation
127from lp.soyuz.interfaces.component import IComponentSet127from lp.soyuz.interfaces.component import IComponentSet
128from lp.soyuz.interfaces.packageset import IPackagesetSet128from lp.soyuz.interfaces.packageset import IPackagesetSet
129from lp.soyuz.interfaces.processor import IProcessorFamilySet
129from lp.soyuz.interfaces.publishing import PackagePublishingStatus130from lp.soyuz.interfaces.publishing import PackagePublishingStatus
130from lp.soyuz.interfaces.section import ISectionSet131from lp.soyuz.interfaces.section import ISectionSet
131from lp.soyuz.model.buildqueue import BuildQueue132from lp.soyuz.model.buildqueue import BuildQueue
@@ -613,6 +614,38 @@
613 productseries=productseries,614 productseries=productseries,
614 name=name)615 name=name)
615616
617 def makeProcessor(self, family, name, title=None, description=None):
618 """Create a new processor.
619
620 :param family: Family of the processor
621 :param name: Name of the processor
622 :param title: Optional title
623 :param description: Optional description
624 :return: A `IProcessor`
625 """
626 if title is None:
627 title = "The %s processor" % name
628 if description is None:
629 description = "The %s and processor and compatible processors"
630 return family.addProcessor(name, title, description)
631
632 def makeProcessorFamily(self, name, title=None, description=None,
633 restricted=False):
634 """Create a new processor family.
635
636 :param name: Name of the family (e.g. x86)
637 :param title: Optional title of the family
638 :param description: Optional extended description
639 :param restricted: Whether the processor family is restricted
640 :return: A `IProcessorFamily`
641 """
642 if description is None:
643 description = "Description of the %s processor family" % name
644 if title is None:
645 title = "%s and compatible processors." % name
646 return getUtility(IProcessorFamilySet).new(name, title, description,
647 restricted=restricted)
648
616 def makeProductRelease(self, milestone=None, product=None,649 def makeProductRelease(self, milestone=None, product=None,
617 productseries=None):650 productseries=None):
618 if milestone is None:651 if milestone is None:

Subscribers

People subscribed via source and target branches

to status/vote changes: