Merge lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1 into lp:launchpad/db-devel
- 567922-binarypackagebuild-new-table-1
- Merge into db-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Aaron Bentley | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 9405 | ||||
Proposed branch: | lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1 | ||||
Merge into: | lp:launchpad/db-devel | ||||
Prerequisite: | lp:~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-4 | ||||
Diff against target: |
1092 lines (+252/-243) (has conflicts) 20 files modified
lib/lp/buildmaster/doc/buildfarmjob.txt (+0/-11) lib/lp/buildmaster/interfaces/buildfarmjob.py (+65/-73) lib/lp/buildmaster/interfaces/packagebuild.py (+14/-13) lib/lp/buildmaster/model/buildfarmjob.py (+37/-23) lib/lp/buildmaster/model/packagebuild.py (+18/-4) lib/lp/buildmaster/tests/test_buildfarmjob.py (+1/-4) lib/lp/buildmaster/tests/test_packagebuild.py (+4/-0) lib/lp/code/configure.zcml (+0/-1) lib/lp/soyuz/configure.zcml (+0/-2) lib/lp/soyuz/doc/build.txt (+3/-2) lib/lp/soyuz/interfaces/binarypackagebuild.py (+28/-11) lib/lp/soyuz/model/binarypackagebuild.py (+56/-62) lib/lp/soyuz/model/sourcepackagerelease.py (+12/-10) lib/lp/soyuz/templates/build-index.pt (+1/-1) lib/lp/soyuz/templates/builds-list.pt (+2/-2) lib/lp/soyuz/tests/test_build.py (+7/-13) lib/lp/soyuz/tests/test_buildpackagejob.py (+0/-4) lib/lp/translations/configure.zcml (+1/-3) lib/lp/translations/model/translationtemplatesbuildjob.py (+1/-1) lib/lp/translations/tests/test_translationtemplatesbuildjob.py (+2/-3) Text conflict in lib/lp/buildmaster/interfaces/buildbase.py Text conflict in lib/lp/buildmaster/model/buildbase.py Text conflict in lib/lp/buildmaster/tests/test_buildbase.py |
||||
To merge this branch: | bzr merge lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Aaron Bentley (community) | Approve | ||
Review via email: mp+24401@code.launchpad.net |
Commit message
Description of the change
This branch is part of a pipeline for
https:/
https:/
Overview
========
This branch *finally* starts the work to switch our BinaryPackageBuild class to the new binarypackagebuild table (using the delegated PackageBuild/
Details
=======
It updates the SQLBase _table to BinaryPackageBuild and then deals with the fallout to ensure that the stated interface is still provided.
This branch is dependent on the pending schema patch in a previous branch.
To test
=======
First update the test db schema (required as the db patch still needs to be updated to remove the old build table):
psql launchpad_
bin/py database/
And then:
bin/test -vv -m soyuz.tests.
The next branch will continue to update the BinaryPackageBuild implementation to get the rest of the tests working.
Aaron Bentley (abentley) wrote : | # |
Michael Nelson (michael.nelson) wrote : | # |
On Mon, May 3, 2010 at 5:55 PM, Aaron Bentley <email address hidden> wrote:
> distro_series should be defined on IPackageBuild, because it's common to all packages, even though the implementation will differ for ISourcePackageR
Thanks - I added it but returned None on PackageBuild (similar to the
other attributes) as raising NotImplementedError for attributes means
that the exception is raised during assertProvides(), or is there a
better way?
>
> diff lines 342-343 need to be re-indented.
Done.
>
> I'm also concerned about the split between IPackageBuild and IPackageBuildDe
Thanks for taking the extra time to improve the design beyond the
actual review itself! You were spot on... I'd started getting mixed up
while trying to find places to move methods to. I've removed
IPackageBuildDe
instead created a mixin class PackageBuildHan
be used to provide an implementation on derived classes (ie. this
implementation can be shared between BinaryPackageBuilds and
SPRBuilds, as it is currently with BuildBase).
I've attached the incremental of the above, but if it's ok with you,
I'll also do a second incremental to get rid of IBuildFarmJobDe
for the same reason you've outlined above.
1 | === modified file 'lib/lp/buildmaster/interfaces/packagebuild.py' |
2 | --- lib/lp/buildmaster/interfaces/packagebuild.py 2010-04-29 15:20:09 +0000 |
3 | +++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-04 12:07:35 +0000 |
4 | @@ -6,7 +6,6 @@ |
5 | __all__ = [ |
6 | 'IPackageBuild', |
7 | 'IPackageBuildSource', |
8 | - 'IPackageBuildDerived', |
9 | ] |
10 | |
11 | |
12 | @@ -19,6 +18,7 @@ |
13 | from canonical.launchpad.interfaces.librarian import ILibraryFileAlias |
14 | from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob |
15 | from lp.registry.interfaces.distribution import IDistribution |
16 | +from lp.registry.interfaces.distroseries import IDistroSeries |
17 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
18 | from lp.soyuz.interfaces.archive import IArchive |
19 | |
20 | @@ -76,6 +76,12 @@ |
21 | title=_("Distribution"), required=True, |
22 | description=_("Shortcut for its distribution."))) |
23 | |
24 | + distro_series = exported( |
25 | + Reference( |
26 | + schema=IDistroSeries, |
27 | + title=_("Distribution series"), required=True, |
28 | + description=_("Shortcut for its distribution series."))) |
29 | + |
30 | def getUploaderCommand(distro_series, upload_leaf, uploader_logfilename): |
31 | """Get the command to run as the uploader. |
32 | |
33 | @@ -138,6 +144,13 @@ |
34 | upload log. |
35 | """ |
36 | |
37 | + def handleStatus(status, librarian, slave_status): |
38 | + """Handle a finished build status from a slave. |
39 | + |
40 | + :param status: Slave build status string with 'BuildStatus.' stripped. |
41 | + :param slave_status: A dict as returned by IBuilder.slaveStatus |
42 | + """ |
43 | + |
44 | |
45 | class IPackageBuildSource(Interface): |
46 | """A utility of this interface used to create _things_.""" |
47 | @@ -149,15 +162,3 @@ |
48 | :param pocket: An item of `PackagePublishingPocket`. |
49 | :param dependencies: An optional debian-like dependency line. |
50 | """ |
51 | - |
52 | - |
53 | -class IPackageBuildDerived(Interface): |
54 | - """Classes deriving from IPackageBuild inherit the default handleStatus. |
55 | - """ |
56 | - def handleStatus(status, librarian, slave_status): |
57 | - """Handle a finished build status from a slave. |
58 | - |
59 | - :param status: Slave build status string with 'BuildStatus.' stripped. |
60 | - :param slave_status: A dict as returned by IBuilder.slaveStatus |
61 | - """ |
62 | - |
63 | |
64 | === modified file 'lib/lp/buildmaster/model/packagebuild.py' |
65 | --- lib/lp/buildmaster/model/packagebuild.py 2010-04-30 16:12:05 +0000 |
66 | +++ lib/lp/buildmaster/model/packagebuild.py 2010-05-04 12:07:35 +0000 |
67 | @@ -23,7 +23,7 @@ |
68 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
69 | from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource |
70 | from lp.buildmaster.interfaces.packagebuild import ( |
71 | - IPackageBuild, IPackageBuildDerived, IPackageBuildSource) |
72 | + IPackageBuild, IPackageBuildSource) |
73 | from lp.buildmaster.model.buildbase import BuildBase |
74 | from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived |
75 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
76 | @@ -58,7 +58,11 @@ |
77 | build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id') |
78 | |
79 | policy_name = 'buildd' |
80 | + |
81 | + # The following two properties are part of the IPackageBuild |
82 | + # interface, but need to be provided by derived classes. |
83 | distribution = None |
84 | + distro_series = None |
85 | |
86 | def __init__(self, build_farm_job, archive, pocket, |
87 | dependencies=None): |
88 | @@ -150,14 +154,25 @@ |
89 | """See `IPackageBuild`.""" |
90 | raise NotImplementedError |
91 | |
92 | + def handleStatus(self, status, librarian, slave_status): |
93 | + """See `IPackageBuild`.""" |
94 | + raise NotImplementedError |
95 | + |
96 | |
97 | class PackageBuildDerived: |
98 | - """See `IPackageBuildDerived`.""" |
99 | - implements(IPackageBuildDerived) |
100 | delegates(IPackageBuild, context="package_build") |
101 | |
102 | + |
103 | +class PackageBuildStatusHandlerMixin: |
104 | + """A mixin to provide the common implementation of handleStatus. |
105 | + |
106 | + This can be used by classes based on PackageBuild to provide |
107 | + the implementation of handleStatus, ensuring that the methods |
108 | + called during handleStatus are called on the top-level object |
109 | + first. |
110 | + """ |
111 | def handleStatus(self, status, librarian, slave_status): |
112 | - """See `IPackageBuildDerived`.""" |
113 | + """See `IPackageBuild`.""" |
114 | return BuildBase.handleStatus(self, status, librarian, slave_status) |
115 | |
116 | # The following private handlers currently re-use the BuildBase |
117 | |
118 | === modified file 'lib/lp/buildmaster/tests/test_packagebuild.py' |
119 | --- lib/lp/buildmaster/tests/test_packagebuild.py 2010-04-30 16:11:03 +0000 |
120 | +++ lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-04 12:07:35 +0000 |
121 | @@ -89,6 +89,9 @@ |
122 | self.assertRaises( |
123 | NotImplementedError, self.package_build.verifySuccessfulUpload) |
124 | self.assertRaises(NotImplementedError, self.package_build.notify) |
125 | + self.assertRaises( |
126 | + NotImplementedError, self.package_build.handleStatus, |
127 | + None, None, None) |
128 | |
129 | def test_default_values(self): |
130 | # PackageBuild has a number of default values. |
131 | @@ -96,6 +99,7 @@ |
132 | self.failUnlessEqual( |
133 | 'multiverse', self.package_build.current_component.name) |
134 | self.failUnlessEqual(None, self.package_build.distribution) |
135 | + self.failUnlessEqual(None, self.package_build.distro_series) |
136 | |
137 | def test_log_url(self): |
138 | # The url of the build log file is determined by the PackageBuild. |
139 | |
140 | === modified file 'lib/lp/soyuz/model/binarypackagebuild.py' |
141 | --- lib/lp/soyuz/model/binarypackagebuild.py 2010-04-29 08:20:20 +0000 |
142 | +++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-04 09:45:26 +0000 |
143 | @@ -199,8 +199,8 @@ |
144 | def was_built(self): |
145 | """See `IBuild`""" |
146 | return self.status not in [BuildStatus.NEEDSBUILD, |
147 | - BuildStatus.BUILDING, |
148 | - BuildStatus.SUPERSEDED] |
149 | + BuildStatus.BUILDING, |
150 | + BuildStatus.SUPERSEDED] |
151 | |
152 | @property |
153 | def arch_tag(self): |
Michael Nelson (michael.nelson) wrote : | # |
On Tue, May 4, 2010 at 2:14 PM, Michael Nelson
<email address hidden> wrote:
...
> I've attached the incremental of the above, but if it's ok with you,
> I'll also do a second incremental to get rid of IBuildFarmJobDe
> for the same reason you've outlined above.
>
See attached for the removal of the IBuildFarmJobDe
above. I also realised while doing this that I don't need the separate
mixin, and have instead provided the shared implementation on the
BuildFarmJobDer
tested with:
bin/test -vv -t test_buildfarmjob -t test_packagebuild -t
test_sourcepack
-Michael
1 | === modified file 'lib/lp/buildmaster/doc/buildfarmjob.txt' |
2 | --- lib/lp/buildmaster/doc/buildfarmjob.txt 2010-04-28 10:59:12 +0000 |
3 | +++ lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-04 13:42:25 +0000 |
4 | @@ -29,17 +29,6 @@ |
5 | |
6 | For more details, please refer to lp.buildmaster.tests.test_buildfarmjob. |
7 | |
8 | -BuildFarmJobDerived |
9 | -=================== |
10 | - |
11 | -BuildFarmJobDerived exists to encapsulate the functionality required |
12 | -by classes delegating IBuildFarmJob. |
13 | - |
14 | - >>> from lp.buildmaster.interfaces.buildfarmjob import ( |
15 | - ... IBuildFarmJobDerived) |
16 | - >>> verifyObject(IBuildFarmJobDerived, BuildFarmJobDerived()) |
17 | - True |
18 | - |
19 | This class also includes the getByJob() class method used to find the |
20 | instance of a specific build-farm job implementation associated with a |
21 | given Job instance which must be called in the context of a concrete |
22 | |
23 | === modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py' |
24 | --- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-04-30 16:11:03 +0000 |
25 | +++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-04 13:42:25 +0000 |
26 | @@ -11,7 +11,6 @@ |
27 | 'IBuildFarmJob', |
28 | 'IBuildFarmJobOld', |
29 | 'IBuildFarmJobSource', |
30 | - 'IBuildFarmJobDerived', |
31 | 'BuildFarmJobType', |
32 | ] |
33 | |
34 | @@ -106,6 +105,71 @@ |
35 | def jobAborted(): |
36 | """'Job aborted' life cycle event, handle as appropriate.""" |
37 | |
38 | + def addCandidateSelectionCriteria(processor, virtualized): |
39 | + """Provide a sub-query to refine the candidate job selection. |
40 | + |
41 | + Return a sub-query to narrow down the list of candidate jobs. |
42 | + The sub-query will become part of an "outer query" and is free to |
43 | + refer to the `BuildQueue` and `Job` tables already utilized in the |
44 | + latter. |
45 | + |
46 | + Example (please see the `BuildPackageJob` implementation for a |
47 | + complete example): |
48 | + |
49 | + SELECT TRUE |
50 | + FROM Archive, Build, BuildPackageJob, DistroArchSeries |
51 | + WHERE |
52 | + BuildPackageJob.job = Job.id AND |
53 | + .. |
54 | + |
55 | + :param processor: the type of processor that the candidate jobs are |
56 | + expected to run on. |
57 | + :param virtualized: whether the candidate jobs are expected to run on |
58 | + the `processor` natively or inside a virtual machine. |
59 | + :return: a string containing a sub-query that narrows down the list of |
60 | + candidate jobs. |
61 | + """ |
62 | + |
63 | + def postprocessCandidate(job, logger): |
64 | + """True if the candidate job is fine and should be dispatched |
65 | + to a builder, False otherwise. |
66 | + |
67 | + :param job: The `BuildQueue` instance to be scrutinized. |
68 | + :param logger: The logger to use. |
69 | + |
70 | + :return: True if the candidate job should be dispatched |
71 | + to a builder, False otherwise. |
72 | + """ |
73 | + |
74 | + def getByJob(job): |
75 | + """Get the specific `IBuildFarmJob` for the given `Job`. |
76 | + |
77 | + Invoked on the specific `IBuildFarmJob`-implementing class that |
78 | + has an entry associated with `job`. |
79 | + """ |
80 | + |
81 | + def generateSlaveBuildCookie(): |
82 | + """Produce a cookie for the slave as a token of the job it's doing. |
83 | + |
84 | + The cookie need not be unique, but should be hard for a |
85 | + compromised slave to guess. |
86 | + |
87 | + :return: a hard-to-guess ASCII string that can be reproduced |
88 | + accurately based on this job's properties. |
89 | + """ |
90 | + |
91 | + def makeJob(): |
92 | + """Create the specific job relating this with an lp.services.job. |
93 | + |
94 | + XXX 2010-04-26 michael.nelson bug=567922 |
95 | + Once all *Build classes are using BuildFarmJob we can lose the |
96 | + 'specific_job' attributes and simply have a reference to the |
97 | + services job directly on the BuildFarmJob. |
98 | + """ |
99 | + |
100 | + def cleanUp(): |
101 | + """Job's finished. Delete its supporting data.""" |
102 | + |
103 | |
104 | class IBuildFarmJob(IBuildFarmJobOld): |
105 | """Operations that jobs for the build farm must implement.""" |
106 | @@ -179,78 +243,6 @@ |
107 | |
108 | title = exported(TextLine(title=_("Title"), required=False)) |
109 | |
110 | - def makeJob(): |
111 | - """Create the specific job relating this with an lp.services.job. |
112 | - |
113 | - XXX 2010-04-26 michael.nelson bug=567922 |
114 | - Once all *Build classes are using BuildFarmJob we can lose the |
115 | - 'specific_job' attributes and simply have a reference to the |
116 | - services job directly on the BuildFarmJob. |
117 | - """ |
118 | - |
119 | - |
120 | -class IBuildFarmJobDerived(Interface): |
121 | - """Common functionality required by classes delegating IBuildFarmJob. |
122 | - |
123 | - An implementation of this class must setup the necessary delegation. |
124 | - """ |
125 | - |
126 | - def getByJob(job): |
127 | - """Get the specific `IBuildFarmJob` for the given `Job`. |
128 | - |
129 | - Invoked on the specific `IBuildFarmJob`-implementing class that |
130 | - has an entry associated with `job`. |
131 | - """ |
132 | - |
133 | - def addCandidateSelectionCriteria(processor, virtualized): |
134 | - """Provide a sub-query to refine the candidate job selection. |
135 | - |
136 | - Return a sub-query to narrow down the list of candidate jobs. |
137 | - The sub-query will become part of an "outer query" and is free to |
138 | - refer to the `BuildQueue` and `Job` tables already utilized in the |
139 | - latter. |
140 | - |
141 | - Example (please see the `BuildPackageJob` implementation for a |
142 | - complete example): |
143 | - |
144 | - SELECT TRUE |
145 | - FROM Archive, Build, BuildPackageJob, DistroArchSeries |
146 | - WHERE |
147 | - BuildPackageJob.job = Job.id AND |
148 | - .. |
149 | - |
150 | - :param processor: the type of processor that the candidate jobs are |
151 | - expected to run on. |
152 | - :param virtualized: whether the candidate jobs are expected to run on |
153 | - the `processor` natively or inside a virtual machine. |
154 | - :return: a string containing a sub-query that narrows down the list of |
155 | - candidate jobs. |
156 | - """ |
157 | - |
158 | - def postprocessCandidate(job, logger): |
159 | - """True if the candidate job is fine and should be dispatched |
160 | - to a builder, False otherwise. |
161 | - |
162 | - :param job: The `BuildQueue` instance to be scrutinized. |
163 | - :param logger: The logger to use. |
164 | - |
165 | - :return: True if the candidate job should be dispatched |
166 | - to a builder, False otherwise. |
167 | - """ |
168 | - |
169 | - def generateSlaveBuildCookie(): |
170 | - """Produce a cookie for the slave as a token of the job it's doing. |
171 | - |
172 | - The cookie need not be unique, but should be hard for a |
173 | - compromised slave to guess. |
174 | - |
175 | - :return: a hard-to-guess ASCII string that can be reproduced |
176 | - accurately based on this job's properties. |
177 | - """ |
178 | - |
179 | - def cleanUp(): |
180 | - """Job's finished. Delete its supporting data.""" |
181 | - |
182 | |
183 | class IBuildFarmJobSource(Interface): |
184 | """A utility of BuildFarmJob used to create _things_.""" |
185 | |
186 | === modified file 'lib/lp/buildmaster/model/buildfarmjob.py' |
187 | --- lib/lp/buildmaster/model/buildfarmjob.py 2010-04-30 16:12:05 +0000 |
188 | +++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-04 13:42:25 +0000 |
189 | @@ -14,7 +14,6 @@ |
190 | |
191 | from lazr.delegates import delegates |
192 | |
193 | -import hashlib |
194 | import pytz |
195 | |
196 | from storm.locals import Bool, DateTime, Int, Reference, Storm |
197 | @@ -32,8 +31,8 @@ |
198 | |
199 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
200 | from lp.buildmaster.interfaces.buildfarmjob import ( |
201 | - BuildFarmJobType, IBuildFarmJob, IBuildFarmJobDerived, |
202 | - IBuildFarmJobOld, IBuildFarmJobSource) |
203 | + BuildFarmJobType, IBuildFarmJob, IBuildFarmJobOld, |
204 | + IBuildFarmJobSource) |
205 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
206 | |
207 | |
208 | @@ -63,6 +62,10 @@ |
209 | """See `IBuildFarmJobOld`.""" |
210 | raise NotImplementedError |
211 | |
212 | + def getByJob(self): |
213 | + """See `IBuildFarmJobOld`.""" |
214 | + raise NotImplementedError |
215 | + |
216 | def jobStarted(self): |
217 | """See `IBuildFarmJobOld`.""" |
218 | pass |
219 | @@ -75,8 +78,27 @@ |
220 | """See `IBuildFarmJobOld`.""" |
221 | pass |
222 | |
223 | + @staticmethod |
224 | + def addCandidateSelectionCriteria(processor, virtualized): |
225 | + """See `IBuildFarmJobOld`.""" |
226 | + return ('') |
227 | + |
228 | + @staticmethod |
229 | + def postprocessCandidate(job, logger): |
230 | + """See `IBuildFarmJobOld`.""" |
231 | + return True |
232 | + |
233 | + def cleanUp(self): |
234 | + """See `IBuildFarmJob`.""" |
235 | + Store.of(self).remove(self) |
236 | + |
237 | + def generateSlaveBuildCookie(self): |
238 | + """See `IBuildFarmJobOld`.""" |
239 | + raise NotImplementedError |
240 | + |
241 | |
242 | class BuildFarmJobOldDerived: |
243 | + """Setup the delegation and provide some common implementation.""" |
244 | delegates(IBuildFarmJobOld, context='build_farm_job') |
245 | |
246 | def __init__(self, *args, **kwargs): |
247 | @@ -102,22 +124,12 @@ |
248 | |
249 | @classmethod |
250 | def getByJob(cls, job): |
251 | - """See `IBuildFarmJobDerived`.""" |
252 | + """See `IBuildFarmJobOld`.""" |
253 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
254 | return store.find(cls, cls.job == job).one() |
255 | |
256 | - @staticmethod |
257 | - def addCandidateSelectionCriteria(processor, virtualized): |
258 | - """See `IBuildFarmJobDerived`.""" |
259 | - return ('') |
260 | - |
261 | - @staticmethod |
262 | - def postprocessCandidate(job, logger): |
263 | - """See `IBuildFarmJobDerived`.""" |
264 | - return True |
265 | - |
266 | def generateSlaveBuildCookie(self): |
267 | - """See `IBuildFarmJobDerived`.""" |
268 | + """See `IBuildFarmJobOld`.""" |
269 | buildqueue = getUtility(IBuildQueueSet).getByJob(self.job) |
270 | |
271 | if buildqueue.processor is None: |
272 | @@ -136,10 +148,6 @@ |
273 | |
274 | return hashlib.sha1(contents).hexdigest() |
275 | |
276 | - def cleanUp(self): |
277 | - """See `IBuildFarmJob`.""" |
278 | - Store.of(self).remove(self) |
279 | - |
280 | |
281 | class BuildFarmJob(BuildFarmJobOld, Storm): |
282 | """A base implementation for `IBuildFarmJob` classes.""" |
283 | @@ -258,8 +266,16 @@ |
284 | """ |
285 | return None |
286 | |
287 | + def cleanUp(self): |
288 | + """See `IBuildFarmJobOld`. |
289 | + |
290 | + XXX 2010-05-04 michael.nelson bug=570939 |
291 | + This can be removed once IBuildFarmJobOld is no longer used |
292 | + and services jobs are linked directly to IBuildFarmJob. |
293 | + """ |
294 | + pass |
295 | + |
296 | |
297 | class BuildFarmJobDerived: |
298 | - """See `IBuildFarmJobDerived`.""" |
299 | - implements(IBuildFarmJobDerived) |
300 | + implements(IBuildFarmJob) |
301 | delegates(IBuildFarmJob, context='build_farm_job') |
302 | |
303 | === modified file 'lib/lp/buildmaster/model/packagebuild.py' |
304 | --- lib/lp/buildmaster/model/packagebuild.py 2010-05-04 12:07:35 +0000 |
305 | +++ lib/lp/buildmaster/model/packagebuild.py 2010-05-04 13:47:11 +0000 |
306 | @@ -160,17 +160,13 @@ |
307 | |
308 | |
309 | class PackageBuildDerived: |
310 | + """Setup the delegation for package build. |
311 | + |
312 | + This class also provides some common implementation for handling |
313 | + build status. |
314 | + """ |
315 | delegates(IPackageBuild, context="package_build") |
316 | |
317 | - |
318 | -class PackageBuildStatusHandlerMixin: |
319 | - """A mixin to provide the common implementation of handleStatus. |
320 | - |
321 | - This can be used by classes based on PackageBuild to provide |
322 | - the implementation of handleStatus, ensuring that the methods |
323 | - called during handleStatus are called on the top-level object |
324 | - first. |
325 | - """ |
326 | def handleStatus(self, status, librarian, slave_status): |
327 | """See `IPackageBuild`.""" |
328 | return BuildBase.handleStatus(self, status, librarian, slave_status) |
329 | |
330 | === modified file 'lib/lp/code/configure.zcml' |
331 | --- lib/lp/code/configure.zcml 2010-04-30 15:05:53 +0000 |
332 | +++ lib/lp/code/configure.zcml 2010-05-04 13:42:25 +0000 |
333 | @@ -1024,7 +1024,6 @@ |
334 | <class |
335 | class="lp.code.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob"> |
336 | <allow interface="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/> |
337 | - <allow interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
338 | </class> |
339 | |
340 | <securedutility |
341 | |
342 | === modified file 'lib/lp/soyuz/configure.zcml' |
343 | --- lib/lp/soyuz/configure.zcml 2010-04-20 14:30:00 +0000 |
344 | +++ lib/lp/soyuz/configure.zcml 2010-05-04 13:42:25 +0000 |
345 | @@ -848,8 +848,6 @@ |
346 | class="lp.soyuz.model.buildpackagejob.BuildPackageJob"> |
347 | <allow |
348 | interface="lp.soyuz.interfaces.buildpackagejob.IBuildPackageJob"/> |
349 | - <allow |
350 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
351 | </class> |
352 | <!-- |
353 | The registration below is used to discover all build farm job classes |
354 | |
355 | === modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py' |
356 | --- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-04-28 13:57:13 +0000 |
357 | +++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-04 13:42:25 +0000 |
358 | @@ -13,7 +13,6 @@ |
359 | |
360 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
361 | from lp.buildmaster.interfaces.builder import IBuilderSet |
362 | -from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobDerived |
363 | from lp.soyuz.interfaces.archive import ArchivePurpose |
364 | from lp.soyuz.interfaces.buildfarmbuildjob import IBuildFarmBuildJob |
365 | from lp.soyuz.interfaces.buildpackagejob import IBuildPackageJob |
366 | @@ -235,6 +234,3 @@ |
367 | build_farm_job = bq.specific_job |
368 | self.assertProvides(build_farm_job, IBuildPackageJob) |
369 | self.assertProvides(build_farm_job, IBuildFarmBuildJob) |
370 | - self.assertProvides(build_farm_job, IBuildFarmJobDerived) |
371 | - |
372 | - |
373 | |
374 | === modified file 'lib/lp/translations/configure.zcml' |
375 | --- lib/lp/translations/configure.zcml 2010-04-22 07:33:12 +0000 |
376 | +++ lib/lp/translations/configure.zcml 2010-05-04 13:42:25 +0000 |
377 | @@ -578,9 +578,7 @@ |
378 | <allow |
379 | interface="lp.code.interfaces.branchjob.IBranchJob"/> |
380 | <allow |
381 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"/> |
382 | - <allow |
383 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
384 | + interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobOld"/> |
385 | </class> |
386 | <securedutility |
387 | component="lp.translations.model.translationtemplatesbuildjob.TranslationTemplatesBuildJob" |
388 | |
389 | === modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py' |
390 | --- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-04-30 16:11:03 +0000 |
391 | +++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-04 13:42:25 +0000 |
392 | @@ -147,7 +147,7 @@ |
393 | |
394 | @classmethod |
395 | def getByJob(cls, job): |
396 | - """See `IBuildFarmJobDerived`. |
397 | + """See `IBuildFarmJob`. |
398 | |
399 | Overridden here to search via a BranchJob, rather than a Job. |
400 | """ |
401 | |
402 | === modified file 'lib/lp/translations/tests/test_translationtemplatesbuildjob.py' |
403 | --- lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-04-30 16:11:03 +0000 |
404 | +++ lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-04 13:42:25 +0000 |
405 | @@ -19,7 +19,7 @@ |
406 | from lp.testing import TestCaseWithFactory |
407 | |
408 | from lp.buildmaster.interfaces.buildfarmjob import ( |
409 | - IBuildFarmJobOld, IBuildFarmJobDerived) |
410 | + IBuildFarmJobOld) |
411 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
412 | from lp.buildmaster.model.buildqueue import BuildQueue |
413 | from lp.code.interfaces.branch import IBranchSet |
414 | @@ -54,9 +54,8 @@ |
415 | |
416 | def test_new_TranslationTemplatesBuildJob(self): |
417 | # TranslationTemplateBuildJob implements IBuildFarmJobOld, |
418 | - # IBuildFarmJobDerived, and IBranchJob. |
419 | + # and IBranchJob. |
420 | verifyObject(IBranchJob, self.specific_job) |
421 | - verifyObject(IBuildFarmJobDerived, self.specific_job) |
422 | verifyObject(IBuildFarmJobOld, self.specific_job) |
423 | |
424 | # Each of these jobs knows the branch it will operate on. |
Aaron Bentley (abentley) wrote : | # |
Looks like a good improvement.
Preview Diff
1 | === modified file 'lib/lp/buildmaster/doc/buildfarmjob.txt' |
2 | --- lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-05 15:51:38 +0000 |
3 | +++ lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-05 15:51:40 +0000 |
4 | @@ -29,17 +29,6 @@ |
5 | |
6 | For more details, please refer to lp.buildmaster.tests.test_buildfarmjob. |
7 | |
8 | -BuildFarmJobDerived |
9 | -=================== |
10 | - |
11 | -BuildFarmJobDerived exists to encapsulate the functionality required |
12 | -by classes delegating IBuildFarmJob. |
13 | - |
14 | - >>> from lp.buildmaster.interfaces.buildfarmjob import ( |
15 | - ... IBuildFarmJobDerived) |
16 | - >>> verifyObject(IBuildFarmJobDerived, BuildFarmJobDerived()) |
17 | - True |
18 | - |
19 | This class also includes the getByJob() class method used to find the |
20 | instance of a specific build-farm job implementation associated with a |
21 | given Job instance which must be called in the context of a concrete |
22 | |
23 | === modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py' |
24 | --- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-05 15:51:38 +0000 |
25 | +++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-05 15:51:40 +0000 |
26 | @@ -11,7 +11,6 @@ |
27 | 'IBuildFarmJob', |
28 | 'IBuildFarmJobOld', |
29 | 'IBuildFarmJobSource', |
30 | - 'IBuildFarmJobDerived', |
31 | 'BuildFarmJobType', |
32 | ] |
33 | |
34 | @@ -106,6 +105,71 @@ |
35 | def jobAborted(): |
36 | """'Job aborted' life cycle event, handle as appropriate.""" |
37 | |
38 | + def addCandidateSelectionCriteria(processor, virtualized): |
39 | + """Provide a sub-query to refine the candidate job selection. |
40 | + |
41 | + Return a sub-query to narrow down the list of candidate jobs. |
42 | + The sub-query will become part of an "outer query" and is free to |
43 | + refer to the `BuildQueue` and `Job` tables already utilized in the |
44 | + latter. |
45 | + |
46 | + Example (please see the `BuildPackageJob` implementation for a |
47 | + complete example): |
48 | + |
49 | + SELECT TRUE |
50 | + FROM Archive, Build, BuildPackageJob, DistroArchSeries |
51 | + WHERE |
52 | + BuildPackageJob.job = Job.id AND |
53 | + .. |
54 | + |
55 | + :param processor: the type of processor that the candidate jobs are |
56 | + expected to run on. |
57 | + :param virtualized: whether the candidate jobs are expected to run on |
58 | + the `processor` natively or inside a virtual machine. |
59 | + :return: a string containing a sub-query that narrows down the list of |
60 | + candidate jobs. |
61 | + """ |
62 | + |
63 | + def postprocessCandidate(job, logger): |
64 | + """True if the candidate job is fine and should be dispatched |
65 | + to a builder, False otherwise. |
66 | + |
67 | + :param job: The `BuildQueue` instance to be scrutinized. |
68 | + :param logger: The logger to use. |
69 | + |
70 | + :return: True if the candidate job should be dispatched |
71 | + to a builder, False otherwise. |
72 | + """ |
73 | + |
74 | + def getByJob(job): |
75 | + """Get the specific `IBuildFarmJob` for the given `Job`. |
76 | + |
77 | + Invoked on the specific `IBuildFarmJob`-implementing class that |
78 | + has an entry associated with `job`. |
79 | + """ |
80 | + |
81 | + def generateSlaveBuildCookie(): |
82 | + """Produce a cookie for the slave as a token of the job it's doing. |
83 | + |
84 | + The cookie need not be unique, but should be hard for a |
85 | + compromised slave to guess. |
86 | + |
87 | + :return: a hard-to-guess ASCII string that can be reproduced |
88 | + accurately based on this job's properties. |
89 | + """ |
90 | + |
91 | + def makeJob(): |
92 | + """Create the specific job relating this with an lp.services.job. |
93 | + |
94 | + XXX 2010-04-26 michael.nelson bug=567922 |
95 | + Once all *Build classes are using BuildFarmJob we can lose the |
96 | + 'specific_job' attributes and simply have a reference to the |
97 | + services job directly on the BuildFarmJob. |
98 | + """ |
99 | + |
100 | + def cleanUp(): |
101 | + """Job's finished. Delete its supporting data.""" |
102 | + |
103 | |
104 | class IBuildFarmJob(IBuildFarmJobOld): |
105 | """Operations that jobs for the build farm must implement.""" |
106 | @@ -179,78 +243,6 @@ |
107 | |
108 | title = exported(TextLine(title=_("Title"), required=False)) |
109 | |
110 | - def makeJob(): |
111 | - """Create the specific job relating this with an lp.services.job. |
112 | - |
113 | - XXX 2010-04-26 michael.nelson bug=567922 |
114 | - Once all *Build classes are using BuildFarmJob we can lose the |
115 | - 'specific_job' attributes and simply have a reference to the |
116 | - services job directly on the BuildFarmJob. |
117 | - """ |
118 | - |
119 | - |
120 | -class IBuildFarmJobDerived(Interface): |
121 | - """Common functionality required by classes delegating IBuildFarmJob. |
122 | - |
123 | - An implementation of this class must setup the necessary delegation. |
124 | - """ |
125 | - |
126 | - def getByJob(job): |
127 | - """Get the specific `IBuildFarmJob` for the given `Job`. |
128 | - |
129 | - Invoked on the specific `IBuildFarmJob`-implementing class that |
130 | - has an entry associated with `job`. |
131 | - """ |
132 | - |
133 | - def addCandidateSelectionCriteria(processor, virtualized): |
134 | - """Provide a sub-query to refine the candidate job selection. |
135 | - |
136 | - Return a sub-query to narrow down the list of candidate jobs. |
137 | - The sub-query will become part of an "outer query" and is free to |
138 | - refer to the `BuildQueue` and `Job` tables already utilized in the |
139 | - latter. |
140 | - |
141 | - Example (please see the `BuildPackageJob` implementation for a |
142 | - complete example): |
143 | - |
144 | - SELECT TRUE |
145 | - FROM Archive, Build, BuildPackageJob, DistroArchSeries |
146 | - WHERE |
147 | - BuildPackageJob.job = Job.id AND |
148 | - .. |
149 | - |
150 | - :param processor: the type of processor that the candidate jobs are |
151 | - expected to run on. |
152 | - :param virtualized: whether the candidate jobs are expected to run on |
153 | - the `processor` natively or inside a virtual machine. |
154 | - :return: a string containing a sub-query that narrows down the list of |
155 | - candidate jobs. |
156 | - """ |
157 | - |
158 | - def postprocessCandidate(job, logger): |
159 | - """True if the candidate job is fine and should be dispatched |
160 | - to a builder, False otherwise. |
161 | - |
162 | - :param job: The `BuildQueue` instance to be scrutinized. |
163 | - :param logger: The logger to use. |
164 | - |
165 | - :return: True if the candidate job should be dispatched |
166 | - to a builder, False otherwise. |
167 | - """ |
168 | - |
169 | - def generateSlaveBuildCookie(): |
170 | - """Produce a cookie for the slave as a token of the job it's doing. |
171 | - |
172 | - The cookie need not be unique, but should be hard for a |
173 | - compromised slave to guess. |
174 | - |
175 | - :return: a hard-to-guess ASCII string that can be reproduced |
176 | - accurately based on this job's properties. |
177 | - """ |
178 | - |
179 | - def cleanUp(): |
180 | - """Job's finished. Delete its supporting data.""" |
181 | - |
182 | |
183 | class IBuildFarmJobSource(Interface): |
184 | """A utility of BuildFarmJob used to create _things_.""" |
185 | |
186 | === modified file 'lib/lp/buildmaster/interfaces/packagebuild.py' |
187 | --- lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:38 +0000 |
188 | +++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:40 +0000 |
189 | @@ -6,7 +6,6 @@ |
190 | __all__ = [ |
191 | 'IPackageBuild', |
192 | 'IPackageBuildSource', |
193 | - 'IPackageBuildDerived', |
194 | ] |
195 | |
196 | |
197 | @@ -19,6 +18,7 @@ |
198 | from canonical.launchpad.interfaces.librarian import ILibraryFileAlias |
199 | from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob |
200 | from lp.registry.interfaces.distribution import IDistribution |
201 | +from lp.registry.interfaces.distroseries import IDistroSeries |
202 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
203 | from lp.soyuz.interfaces.archive import IArchive |
204 | |
205 | @@ -76,6 +76,12 @@ |
206 | title=_("Distribution"), required=True, |
207 | description=_("Shortcut for its distribution."))) |
208 | |
209 | + distro_series = exported( |
210 | + Reference( |
211 | + schema=IDistroSeries, |
212 | + title=_("Distribution series"), required=True, |
213 | + description=_("Shortcut for its distribution series."))) |
214 | + |
215 | def getUploaderCommand(distro_series, upload_leaf, uploader_logfilename): |
216 | """Get the command to run as the uploader. |
217 | |
218 | @@ -138,6 +144,13 @@ |
219 | upload log. |
220 | """ |
221 | |
222 | + def handleStatus(status, librarian, slave_status): |
223 | + """Handle a finished build status from a slave. |
224 | + |
225 | + :param status: Slave build status string with 'BuildStatus.' stripped. |
226 | + :param slave_status: A dict as returned by IBuilder.slaveStatus |
227 | + """ |
228 | + |
229 | |
230 | class IPackageBuildSource(Interface): |
231 | """A utility of this interface used to create _things_.""" |
232 | @@ -149,15 +162,3 @@ |
233 | :param pocket: An item of `PackagePublishingPocket`. |
234 | :param dependencies: An optional debian-like dependency line. |
235 | """ |
236 | - |
237 | - |
238 | -class IPackageBuildDerived(Interface): |
239 | - """Classes deriving from IPackageBuild inherit the default handleStatus. |
240 | - """ |
241 | - def handleStatus(status, librarian, slave_status): |
242 | - """Handle a finished build status from a slave. |
243 | - |
244 | - :param status: Slave build status string with 'BuildStatus.' stripped. |
245 | - :param slave_status: A dict as returned by IBuilder.slaveStatus |
246 | - """ |
247 | - |
248 | |
249 | === modified file 'lib/lp/buildmaster/model/buildfarmjob.py' |
250 | --- lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:38 +0000 |
251 | +++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:40 +0000 |
252 | @@ -14,7 +14,6 @@ |
253 | |
254 | from lazr.delegates import delegates |
255 | |
256 | -import hashlib |
257 | import pytz |
258 | |
259 | from storm.locals import Bool, DateTime, Int, Reference, Storm |
260 | @@ -32,8 +31,8 @@ |
261 | |
262 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
263 | from lp.buildmaster.interfaces.buildfarmjob import ( |
264 | - BuildFarmJobType, IBuildFarmJob, IBuildFarmJobDerived, |
265 | - IBuildFarmJobOld, IBuildFarmJobSource) |
266 | + BuildFarmJobType, IBuildFarmJob, IBuildFarmJobOld, |
267 | + IBuildFarmJobSource) |
268 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
269 | |
270 | |
271 | @@ -63,6 +62,10 @@ |
272 | """See `IBuildFarmJobOld`.""" |
273 | raise NotImplementedError |
274 | |
275 | + def getByJob(self): |
276 | + """See `IBuildFarmJobOld`.""" |
277 | + raise NotImplementedError |
278 | + |
279 | def jobStarted(self): |
280 | """See `IBuildFarmJobOld`.""" |
281 | pass |
282 | @@ -75,8 +78,27 @@ |
283 | """See `IBuildFarmJobOld`.""" |
284 | pass |
285 | |
286 | + @staticmethod |
287 | + def addCandidateSelectionCriteria(processor, virtualized): |
288 | + """See `IBuildFarmJobOld`.""" |
289 | + return ('') |
290 | + |
291 | + @staticmethod |
292 | + def postprocessCandidate(job, logger): |
293 | + """See `IBuildFarmJobOld`.""" |
294 | + return True |
295 | + |
296 | + def cleanUp(self): |
297 | + """See `IBuildFarmJob`.""" |
298 | + Store.of(self).remove(self) |
299 | + |
300 | + def generateSlaveBuildCookie(self): |
301 | + """See `IBuildFarmJobOld`.""" |
302 | + raise NotImplementedError |
303 | + |
304 | |
305 | class BuildFarmJobOldDerived: |
306 | + """Setup the delegation and provide some common implementation.""" |
307 | delegates(IBuildFarmJobOld, context='build_farm_job') |
308 | |
309 | def __init__(self, *args, **kwargs): |
310 | @@ -102,22 +124,12 @@ |
311 | |
312 | @classmethod |
313 | def getByJob(cls, job): |
314 | - """See `IBuildFarmJobDerived`.""" |
315 | + """See `IBuildFarmJobOld`.""" |
316 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
317 | return store.find(cls, cls.job == job).one() |
318 | |
319 | - @staticmethod |
320 | - def addCandidateSelectionCriteria(processor, virtualized): |
321 | - """See `IBuildFarmJobDerived`.""" |
322 | - return ('') |
323 | - |
324 | - @staticmethod |
325 | - def postprocessCandidate(job, logger): |
326 | - """See `IBuildFarmJobDerived`.""" |
327 | - return True |
328 | - |
329 | def generateSlaveBuildCookie(self): |
330 | - """See `IBuildFarmJobDerived`.""" |
331 | + """See `IBuildFarmJobOld`.""" |
332 | buildqueue = getUtility(IBuildQueueSet).getByJob(self.job) |
333 | |
334 | if buildqueue.processor is None: |
335 | @@ -136,10 +148,6 @@ |
336 | |
337 | return hashlib.sha1(contents).hexdigest() |
338 | |
339 | - def cleanUp(self): |
340 | - """See `IBuildFarmJob`.""" |
341 | - Store.of(self).remove(self) |
342 | - |
343 | |
344 | class BuildFarmJob(BuildFarmJobOld, Storm): |
345 | """A base implementation for `IBuildFarmJob` classes.""" |
346 | @@ -238,8 +246,6 @@ |
347 | @property |
348 | def buildqueue_record(self): |
349 | """See `IBuildFarmJob`.""" |
350 | - # Need to update the db schema for buildpackagejob before |
351 | - # this can be implemented here. |
352 | return None |
353 | |
354 | @property |
355 | @@ -260,8 +266,16 @@ |
356 | """ |
357 | return None |
358 | |
359 | + def cleanUp(self): |
360 | + """See `IBuildFarmJobOld`. |
361 | + |
362 | + XXX 2010-05-04 michael.nelson bug=570939 |
363 | + This can be removed once IBuildFarmJobOld is no longer used |
364 | + and services jobs are linked directly to IBuildFarmJob. |
365 | + """ |
366 | + pass |
367 | + |
368 | |
369 | class BuildFarmJobDerived: |
370 | - """See `IBuildFarmJobDerived`.""" |
371 | - implements(IBuildFarmJobDerived) |
372 | + implements(IBuildFarmJob) |
373 | delegates(IBuildFarmJob, context='build_farm_job') |
374 | |
375 | === modified file 'lib/lp/buildmaster/model/packagebuild.py' |
376 | --- lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:38 +0000 |
377 | +++ lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:40 +0000 |
378 | @@ -8,6 +8,8 @@ |
379 | ] |
380 | |
381 | |
382 | +from lazr.delegates import delegates |
383 | + |
384 | from storm.locals import Int, Reference, Storm, Unicode |
385 | |
386 | from zope.component import getUtility |
387 | @@ -21,7 +23,7 @@ |
388 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
389 | from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource |
390 | from lp.buildmaster.interfaces.packagebuild import ( |
391 | - IPackageBuild, IPackageBuildDerived, IPackageBuildSource) |
392 | + IPackageBuild, IPackageBuildSource) |
393 | from lp.buildmaster.model.buildbase import BuildBase |
394 | from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived |
395 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
396 | @@ -56,7 +58,11 @@ |
397 | build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id') |
398 | |
399 | policy_name = 'buildd' |
400 | + |
401 | + # The following two properties are part of the IPackageBuild |
402 | + # interface, but need to be provided by derived classes. |
403 | distribution = None |
404 | + distro_series = None |
405 | |
406 | def __init__(self, build_farm_job, archive, pocket, |
407 | dependencies=None): |
408 | @@ -148,13 +154,21 @@ |
409 | """See `IPackageBuild`.""" |
410 | raise NotImplementedError |
411 | |
412 | + def handleStatus(self, status, librarian, slave_status): |
413 | + """See `IPackageBuild`.""" |
414 | + raise NotImplementedError |
415 | + |
416 | |
417 | class PackageBuildDerived: |
418 | - """See `IPackageBuildDerived`.""" |
419 | - implements(IPackageBuildDerived) |
420 | + """Setup the delegation for package build. |
421 | + |
422 | + This class also provides some common implementation for handling |
423 | + build status. |
424 | + """ |
425 | + delegates(IPackageBuild, context="package_build") |
426 | |
427 | def handleStatus(self, status, librarian, slave_status): |
428 | - """See `IPackageBuildDerived`.""" |
429 | + """See `IPackageBuild`.""" |
430 | return BuildBase.handleStatus(self, status, librarian, slave_status) |
431 | |
432 | # The following private handlers currently re-use the BuildBase |
433 | |
434 | === modified file 'lib/lp/buildmaster/tests/test_buildfarmjob.py' |
435 | --- lib/lp/buildmaster/tests/test_buildfarmjob.py 2010-05-05 15:51:38 +0000 |
436 | +++ lib/lp/buildmaster/tests/test_buildfarmjob.py 2010-05-05 15:51:40 +0000 |
437 | @@ -68,6 +68,7 @@ |
438 | self.assertEqual(None, self.build_farm_job.builder) |
439 | self.assertEqual(None, self.build_farm_job.log) |
440 | self.assertEqual(None, self.build_farm_job.log_url) |
441 | + self.assertEqual(None, self.build_farm_job.buildqueue_record) |
442 | |
443 | def test_unimplemented_methods(self): |
444 | # A build farm job leaves the implementation of various |
445 | @@ -111,10 +112,6 @@ |
446 | self.build_farm_job.job_type.title, |
447 | self.build_farm_job.title) |
448 | |
449 | - def test_buildqueue_record(self): |
450 | - self.failUnless( |
451 | - False, "Update schema and move buildqueue_record implementation") |
452 | - |
453 | |
454 | def test_suite(): |
455 | return unittest.TestLoader().loadTestsFromName(__name__) |
456 | |
457 | === modified file 'lib/lp/buildmaster/tests/test_packagebuild.py' |
458 | --- lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:51:38 +0000 |
459 | +++ lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:51:40 +0000 |
460 | @@ -89,6 +89,9 @@ |
461 | self.assertRaises( |
462 | NotImplementedError, self.package_build.verifySuccessfulUpload) |
463 | self.assertRaises(NotImplementedError, self.package_build.notify) |
464 | + self.assertRaises( |
465 | + NotImplementedError, self.package_build.handleStatus, |
466 | + None, None, None) |
467 | |
468 | def test_default_values(self): |
469 | # PackageBuild has a number of default values. |
470 | @@ -96,6 +99,7 @@ |
471 | self.failUnlessEqual( |
472 | 'multiverse', self.package_build.current_component.name) |
473 | self.failUnlessEqual(None, self.package_build.distribution) |
474 | + self.failUnlessEqual(None, self.package_build.distro_series) |
475 | |
476 | def test_log_url(self): |
477 | # The url of the build log file is determined by the PackageBuild. |
478 | |
479 | === modified file 'lib/lp/code/configure.zcml' |
480 | --- lib/lp/code/configure.zcml 2010-04-29 13:24:30 +0000 |
481 | +++ lib/lp/code/configure.zcml 2010-05-05 15:51:40 +0000 |
482 | @@ -1024,7 +1024,6 @@ |
483 | <class |
484 | class="lp.code.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob"> |
485 | <allow interface="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/> |
486 | - <allow interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
487 | </class> |
488 | |
489 | <securedutility |
490 | |
491 | === modified file 'lib/lp/soyuz/configure.zcml' |
492 | --- lib/lp/soyuz/configure.zcml 2010-04-20 14:30:00 +0000 |
493 | +++ lib/lp/soyuz/configure.zcml 2010-05-05 15:51:40 +0000 |
494 | @@ -848,8 +848,6 @@ |
495 | class="lp.soyuz.model.buildpackagejob.BuildPackageJob"> |
496 | <allow |
497 | interface="lp.soyuz.interfaces.buildpackagejob.IBuildPackageJob"/> |
498 | - <allow |
499 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
500 | </class> |
501 | <!-- |
502 | The registration below is used to discover all build farm job classes |
503 | |
504 | === modified file 'lib/lp/soyuz/doc/build.txt' |
505 | --- lib/lp/soyuz/doc/build.txt 2010-04-14 17:34:35 +0000 |
506 | +++ lib/lp/soyuz/doc/build.txt 2010-05-05 15:51:40 +0000 |
507 | @@ -72,7 +72,7 @@ |
508 | >>> firefox_build.was_built |
509 | True |
510 | |
511 | - >>> firefox_build.calculated_buildstart |
512 | + >>> firefox_build.date_started |
513 | datetime.datetime(...) |
514 | |
515 | >>> firefox_build.datebuilt |
516 | @@ -895,6 +895,7 @@ |
517 | |
518 | Build records inserted by gina don't provide calculated_buildstart |
519 | value, since they miss fields used in its calculation. |
520 | +TODO: check and update this based on the new model. |
521 | |
522 | >>> gina_build = getUtility(IBinaryPackageBuildSet).getByBuildID(10) |
523 | >>> gina_build.title |
524 | @@ -908,7 +909,7 @@ |
525 | this method is protected by an assertion on valid buildduration and |
526 | datebuilt, it makes the diagnosis of problems in current DB easier. |
527 | |
528 | - >>> gina_build.calculated_buildstart |
529 | + >>> gina_build.date_started |
530 | Traceback (most recent call last): |
531 | ... |
532 | AssertionError: value is not suitable for this build record (10) |
533 | |
534 | === modified file 'lib/lp/soyuz/interfaces/binarypackagebuild.py' |
535 | --- lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-04-12 13:17:34 +0000 |
536 | +++ lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-05-05 15:51:40 +0000 |
537 | @@ -16,11 +16,12 @@ |
538 | ] |
539 | |
540 | from zope.interface import Interface, Attribute |
541 | -from zope.schema import Bool, Int, Object, Text |
542 | +from zope.schema import Bool, Int, Text |
543 | from lazr.enum import EnumeratedType, Item |
544 | |
545 | from canonical.launchpad import _ |
546 | -from lp.buildmaster.interfaces.buildbase import IBuildBase |
547 | +from lp.buildmaster.interfaces.buildbase import BuildStatus |
548 | +from lp.buildmaster.interfaces.packagebuild import IPackageBuild |
549 | from lp.soyuz.interfaces.processor import IProcessor |
550 | from lp.soyuz.interfaces.publishing import ( |
551 | ISourcePackagePublishingHistory) |
552 | @@ -38,21 +39,26 @@ |
553 | _message_prefix = "Cannot rescore build" |
554 | |
555 | |
556 | -class IBinaryPackageBuildView(IBuildBase): |
557 | +class IBinaryPackageBuildView(IPackageBuild): |
558 | """A Build interface for items requiring launchpad.View.""" |
559 | id = Int(title=_('ID'), required=True, readonly=True) |
560 | |
561 | - processor = Object( |
562 | + package_build = Reference( |
563 | + title=_('Package build'), schema=IPackageBuild, required=True, |
564 | + readonly=True, description=_('The base package build')) |
565 | + |
566 | + # Overridden from IBuildFarmJob to ensure required is True. |
567 | + processor = Reference( |
568 | title=_("Processor"), schema=IProcessor, |
569 | required=True, readonly=True, |
570 | description=_("The Processor where this build should be built.")) |
571 | |
572 | - sourcepackagerelease = Object( |
573 | + source_package_release = Reference( |
574 | title=_('Source'), schema=ISourcePackageRelease, |
575 | required=True, readonly=True, |
576 | description=_("The SourcePackageRelease requested to build.")) |
577 | |
578 | - distroarchseries = Object( |
579 | + distro_arch_series = Reference( |
580 | title=_("Architecture"), |
581 | # Really IDistroArchSeries |
582 | schema=Interface, |
583 | @@ -67,7 +73,7 @@ |
584 | required=False, readonly=True, |
585 | description=_("The current source publication for this build."))) |
586 | |
587 | - distroseries = Attribute("Direct parent needed by CanonicalURL") |
588 | + distro_series = Attribute("Direct parent needed by CanonicalURL") |
589 | was_built = Attribute("Whether or not modified by the builddfarm.") |
590 | arch_tag = exported( |
591 | Text(title=_("Architecture tag"), required=False)) |
592 | @@ -93,10 +99,6 @@ |
593 | description=_( |
594 | "Whether or not this build record can be retried."))) |
595 | |
596 | - calculated_buildstart = Attribute( |
597 | - "Emulates a buildstart timestamp by calculating it from " |
598 | - "datebuilt - buildduration.") |
599 | - |
600 | is_virtualized = Attribute( |
601 | "Whether or not this build requires a virtual build host or not.") |
602 | |
603 | @@ -213,6 +215,21 @@ |
604 | class IBinaryPackageBuildSet(Interface): |
605 | """Interface for BinaryPackageBuildSet""" |
606 | |
607 | + def new(distro_arch_series, source_package_release, processor, |
608 | + archive, pocket, status=BuildStatus.NEEDSBUILD, |
609 | + date_created=None): |
610 | + """Create a new `IBinaryPackageBuild`. |
611 | + |
612 | + :param distro_arch_series: An `IDistroArchSeries`. |
613 | + :param source_package_release: An `ISourcePackageRelease`. |
614 | + :param processor: An `IProcessor`. |
615 | + :param archive: An `IArchive` in which context the build is built. |
616 | + :param pocket: An item of `PackagePublishingPocket`. |
617 | + :param status: A `BuildStatus` item indicating the builds status. |
618 | + :param date_created: An optional datetime to ensure multiple builds |
619 | + in the same transaction don't all get the same UTC_NOW. |
620 | + """ |
621 | + |
622 | def getBuildBySRAndArchtag(sourcepackagereleaseID, archtag): |
623 | """Return a build for a SourcePackageRelease and an ArchTag""" |
624 | |
625 | |
626 | === modified file 'lib/lp/soyuz/model/binarypackagebuild.py' |
627 | --- lib/lp/soyuz/model/binarypackagebuild.py 2010-04-15 13:48:46 +0000 |
628 | +++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-05 15:51:40 +0000 |
629 | @@ -11,6 +11,10 @@ |
630 | import logging |
631 | import operator |
632 | |
633 | +from lazr.delegates import delegates |
634 | + |
635 | +from storm.locals import Int, Reference |
636 | + |
637 | from zope.interface import implements |
638 | from zope.component import getUtility |
639 | from zope.security.proxy import removeSecurityProxy |
640 | @@ -18,13 +22,10 @@ |
641 | Desc, In, Join, LeftJoin) |
642 | from storm.store import Store |
643 | from sqlobject import ( |
644 | - StringCol, ForeignKey, IntervalCol, SQLObjectNotFound) |
645 | + ForeignKey, SQLObjectNotFound) |
646 | from sqlobject.sqlbuilder import AND, IN |
647 | |
648 | from canonical.config import config |
649 | -from canonical.database.constants import UTC_NOW |
650 | -from canonical.database.datetimecol import UtcDateTimeCol |
651 | -from canonical.database.enumcol import EnumCol |
652 | from canonical.database.sqlbase import quote_like, SQLBase, sqlvalues |
653 | from canonical.launchpad.components.decoratedresultset import ( |
654 | DecoratedResultSet) |
655 | @@ -43,16 +44,16 @@ |
656 | from lp.archivepublisher.utils import get_ppa_reference |
657 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
658 | from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType |
659 | -from lp.buildmaster.model.buildbase import BuildBase |
660 | +from lp.buildmaster.interfaces.packagebuild import ( |
661 | + IPackageBuild, IPackageBuildSource) |
662 | from lp.buildmaster.model.buildqueue import BuildQueue |
663 | -from lp.registry.interfaces.pocket import PackagePublishingPocket |
664 | +from lp.buildmaster.model.packagebuild import PackageBuildDerived |
665 | from lp.services.job.model.job import Job |
666 | from lp.soyuz.adapters.archivedependencies import get_components_for_building |
667 | from lp.soyuz.interfaces.archive import ArchivePurpose |
668 | from lp.soyuz.interfaces.binarypackagebuild import ( |
669 | BuildSetStatus, CannotBeRescored, IBinaryPackageBuild, |
670 | IBinaryPackageBuildSet) |
671 | -from lp.buildmaster.interfaces.buildbase import IBuildBase |
672 | from lp.soyuz.interfaces.publishing import active_publishing_status |
673 | from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease |
674 | from lp.buildmaster.model.builder import Builder |
675 | @@ -63,37 +64,21 @@ |
676 | PackageUpload, PackageUploadBuild) |
677 | |
678 | |
679 | -class BinaryPackageBuild(BuildBase, SQLBase): |
680 | - implements(IBuildBase, IBinaryPackageBuild) |
681 | - _table = 'Build' |
682 | +class BinaryPackageBuild(PackageBuildDerived, SQLBase): |
683 | + implements(IBinaryPackageBuild) |
684 | + delegates(IPackageBuild, context="package_build") |
685 | + _table = 'BinaryPackageBuild' |
686 | _defaultOrder = 'id' |
687 | |
688 | build_farm_job_type = BuildFarmJobType.PACKAGEBUILD |
689 | |
690 | - datecreated = UtcDateTimeCol(dbName='datecreated', default=UTC_NOW) |
691 | - processor = ForeignKey(dbName='processor', foreignKey='Processor', |
692 | - notNull=True) |
693 | - distroarchseries = ForeignKey(dbName='distroarchseries', |
694 | + package_build_id = Int(name='package_build', allow_none=False) |
695 | + package_build = Reference(package_build_id, 'PackageBuild.id') |
696 | + |
697 | + distro_arch_series = ForeignKey(dbName='distro_arch_series', |
698 | foreignKey='DistroArchSeries', notNull=True) |
699 | - buildstate = EnumCol(dbName='buildstate', notNull=True, |
700 | - schema=BuildStatus) |
701 | - sourcepackagerelease = ForeignKey(dbName='sourcepackagerelease', |
702 | + source_package_release = ForeignKey(dbName='source_package_release', |
703 | foreignKey='SourcePackageRelease', notNull=True) |
704 | - datebuilt = UtcDateTimeCol(dbName='datebuilt', default=None) |
705 | - buildduration = IntervalCol(dbName='buildduration', default=None) |
706 | - buildlog = ForeignKey(dbName='buildlog', foreignKey='LibraryFileAlias', |
707 | - default=None) |
708 | - builder = ForeignKey(dbName='builder', foreignKey='Builder', |
709 | - default=None) |
710 | - pocket = EnumCol(dbName='pocket', schema=PackagePublishingPocket, |
711 | - notNull=True) |
712 | - dependencies = StringCol(dbName='dependencies', default=None) |
713 | - archive = ForeignKey(foreignKey='Archive', dbName='archive', notNull=True) |
714 | - |
715 | - date_first_dispatched = UtcDateTimeCol(dbName='date_first_dispatched') |
716 | - |
717 | - upload_log = ForeignKey( |
718 | - dbName='upload_log', foreignKey='LibraryFileAlias', default=None) |
719 | |
720 | @property |
721 | def buildqueue_record(self): |
722 | @@ -110,9 +95,9 @@ |
723 | results = store.find( |
724 | SourcePackagePublishingHistory, |
725 | SourcePackagePublishingHistory.archive == self.archive, |
726 | - SourcePackagePublishingHistory.distroseries == self.distroseries, |
727 | + SourcePackagePublishingHistory.distroseries == self.distro_series, |
728 | SourcePackagePublishingHistory.sourcepackagerelease == |
729 | - self.sourcepackagerelease) |
730 | + self.source_package_release) |
731 | return results.order_by( |
732 | Desc(SourcePackagePublishingHistory.id)).first() |
733 | |
734 | @@ -130,7 +115,7 @@ |
735 | #assert latest_publication is not None, ( |
736 | # 'Build %d lacks a corresponding source publication.' % self.id) |
737 | if latest_publication is None: |
738 | - return self.sourcepackagerelease.component |
739 | + return self.source_package_release.component |
740 | |
741 | return latest_publication.component |
742 | |
743 | @@ -173,7 +158,7 @@ |
744 | (PackageUpload, LibraryFileAlias, LibraryFileContent), |
745 | PackageUploadBuild.build == self, |
746 | PackageUpload.archive == self.archive, |
747 | - PackageUpload.distroseries == self.distroseries) |
748 | + PackageUpload.distroseries == self.distro_series) |
749 | |
750 | # Return the unique `PackageUpload` record that corresponds to the |
751 | # upload of the result of this `Build`, load the `LibraryFileAlias` |
752 | @@ -182,14 +167,14 @@ |
753 | return DecoratedResultSet(results, operator.itemgetter(0)).one() |
754 | |
755 | @property |
756 | - def distroseries(self): |
757 | + def distro_series(self): |
758 | """See `IBuild`""" |
759 | - return self.distroarchseries.distroseries |
760 | + return self.distro_arch_series.distroseries |
761 | |
762 | @property |
763 | def distribution(self): |
764 | """See `IBuild`""" |
765 | - return self.distroarchseries.distroseries.distribution |
766 | + return self.distro_series.distribution |
767 | |
768 | @property |
769 | def is_virtualized(self): |
770 | @@ -205,22 +190,22 @@ |
771 | def title(self): |
772 | """See `IBuild`""" |
773 | return '%s build of %s %s in %s %s %s' % ( |
774 | - self.distroarchseries.architecturetag, |
775 | - self.sourcepackagerelease.name, |
776 | - self.sourcepackagerelease.version, |
777 | - self.distribution.name, self.distroseries.name, self.pocket.name) |
778 | + self.distro_arch_series.architecturetag, |
779 | + self.source_package_release.name, |
780 | + self.source_package_release.version, |
781 | + self.distribution.name, self.distro_series.name, self.pocket.name) |
782 | |
783 | @property |
784 | def was_built(self): |
785 | """See `IBuild`""" |
786 | - return self.buildstate not in [BuildStatus.NEEDSBUILD, |
787 | - BuildStatus.BUILDING, |
788 | - BuildStatus.SUPERSEDED] |
789 | + return self.status not in [BuildStatus.NEEDSBUILD, |
790 | + BuildStatus.BUILDING, |
791 | + BuildStatus.SUPERSEDED] |
792 | |
793 | @property |
794 | def arch_tag(self): |
795 | """See `IBuild`.""" |
796 | - return self.distroarchseries.architecturetag |
797 | + return self.distro_arch_series.architecturetag |
798 | |
799 | @property |
800 | def distributionsourcepackagerelease(self): |
801 | @@ -230,8 +215,8 @@ |
802 | DistributionSourcePackageRelease) |
803 | |
804 | return DistributionSourcePackageRelease( |
805 | - distribution=self.distroarchseries.distroseries.distribution, |
806 | - sourcepackagerelease=self.sourcepackagerelease) |
807 | + distribution=self.distribution, |
808 | + sourcepackagerelease=self.source_package_release) |
809 | |
810 | @property |
811 | def binarypackages(self): |
812 | @@ -251,7 +236,7 @@ |
813 | from canonical.launchpad.database import ( |
814 | DistroArchSeriesBinaryPackageRelease) |
815 | return [DistroArchSeriesBinaryPackageRelease( |
816 | - self.distroarchseries, bp) |
817 | + self.distro_arch_series, bp) |
818 | for bp in self.binarypackages] |
819 | |
820 | @property |
821 | @@ -260,12 +245,12 @@ |
822 | # First check that the slave scanner would pick up the build record |
823 | # if we reset it. PPA and Partner builds are always ok. |
824 | if (self.archive.purpose == ArchivePurpose.PRIMARY and |
825 | - not self.distroseries.canUploadToPocket(self.pocket)): |
826 | + not self.distro_series.canUploadToPocket(self.pocket)): |
827 | # The slave scanner would not pick this up, so it cannot be |
828 | # re-tried. |
829 | return False |
830 | |
831 | - failed_buildstates = [ |
832 | + failed_statuses = [ |
833 | BuildStatus.FAILEDTOBUILD, |
834 | BuildStatus.MANUALDEPWAIT, |
835 | BuildStatus.CHROOTWAIT, |
836 | @@ -274,20 +259,12 @@ |
837 | |
838 | # If the build is currently in any of the failed states, |
839 | # it may be retried. |
840 | - return self.buildstate in failed_buildstates |
841 | + return self.status in failed_statuses |
842 | |
843 | @property |
844 | def can_be_rescored(self): |
845 | """See `IBuild`.""" |
846 | - return self.buildstate is BuildStatus.NEEDSBUILD |
847 | - |
848 | - @property |
849 | - def calculated_buildstart(self): |
850 | - """See `IBuild`.""" |
851 | - assert self.datebuilt and self.buildduration, ( |
852 | - "value is not suitable for this build record (%d)" |
853 | - % self.id) |
854 | - return self.datebuilt - self.buildduration |
855 | + return self.status is BuildStatus.NEEDSBUILD |
856 | |
857 | def retry(self): |
858 | """See `IBuild`.""" |
859 | @@ -695,6 +672,23 @@ |
860 | class BinaryPackageBuildSet: |
861 | implements(IBinaryPackageBuildSet) |
862 | |
863 | + def new(self, distro_arch_series, source_package_release, processor, |
864 | + archive, pocket, status=BuildStatus.NEEDSBUILD, |
865 | + date_created=None): |
866 | + """See `IBinaryPackageBuildSet`.""" |
867 | + # Create the PackageBuild to which the new BinaryPackageBuild |
868 | + # will delegate. |
869 | + package_build = getUtility(IPackageBuildSource).new( |
870 | + BinaryPackageBuild.build_farm_job_type, |
871 | + archive.require_virtualized, archive, pocket, processor, |
872 | + status) #, date_created) |
873 | + |
874 | + binary_package_build = BinaryPackageBuild( |
875 | + package_build=package_build, |
876 | + distro_arch_series=distro_arch_series, |
877 | + source_package_release=source_package_release) |
878 | + return binary_package_build |
879 | + |
880 | def getBuildBySRAndArchtag(self, sourcepackagereleaseID, archtag): |
881 | """See `IBinaryPackageBuildSet`""" |
882 | clauseTables = ['DistroArchSeries'] |
883 | |
884 | === modified file 'lib/lp/soyuz/model/sourcepackagerelease.py' |
885 | --- lib/lp/soyuz/model/sourcepackagerelease.py 2010-04-12 08:29:02 +0000 |
886 | +++ lib/lp/soyuz/model/sourcepackagerelease.py 2010-05-05 15:51:40 +0000 |
887 | @@ -41,6 +41,7 @@ |
888 | from lp.registry.interfaces.sourcepackage import ( |
889 | SourcePackageType, SourcePackageUrgency) |
890 | from lp.soyuz.interfaces.archive import IArchiveSet, MAIN_ARCHIVE_PURPOSES |
891 | +from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet |
892 | from lp.soyuz.interfaces.packagediff import ( |
893 | PackageDiffAlreadyRequested, PackageDiffStatus) |
894 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
895 | @@ -310,12 +311,12 @@ |
896 | else: |
897 | return 0.0 |
898 | |
899 | - def createBuild(self, distroarchseries, pocket, archive, processor=None, |
900 | + def createBuild(self, distro_arch_series, pocket, archive, processor=None, |
901 | status=None): |
902 | """See ISourcePackageRelease.""" |
903 | # Guess a processor if one is not provided |
904 | if processor is None: |
905 | - pf = distroarchseries.processorfamily |
906 | + pf = distro_arch_series.processorfamily |
907 | # We guess at the first processor in the family |
908 | processor = shortlist(pf.processors)[0] |
909 | |
910 | @@ -325,15 +326,16 @@ |
911 | # Force the current timestamp instead of the default |
912 | # UTC_NOW for the transaction, avoid several row with |
913 | # same datecreated. |
914 | - datecreated = datetime.datetime.now(pytz.timezone('UTC')) |
915 | + date_created = datetime.datetime.now(pytz.timezone('UTC')) |
916 | |
917 | - return BinaryPackageBuild(distroarchseries=distroarchseries, |
918 | - sourcepackagerelease=self, |
919 | - processor=processor, |
920 | - buildstate=status, |
921 | - datecreated=datecreated, |
922 | - pocket=pocket, |
923 | - archive=archive) |
924 | + return getUtility(IBinaryPackageBuildSet).new( |
925 | + distro_arch_series=distro_arch_series, |
926 | + source_package_release=self, |
927 | + processor=processor, |
928 | + status=status, |
929 | + date_created=date_created, |
930 | + pocket=pocket, |
931 | + archive=archive) |
932 | |
933 | def getBuildByArch(self, distroarchseries, archive): |
934 | """See ISourcePackageRelease.""" |
935 | |
936 | === modified file 'lib/lp/soyuz/templates/build-index.pt' |
937 | --- lib/lp/soyuz/templates/build-index.pt 2010-02-24 13:39:16 +0000 |
938 | +++ lib/lp/soyuz/templates/build-index.pt 2010-05-05 15:51:40 +0000 |
939 | @@ -169,7 +169,7 @@ |
940 | <tal:built condition="context/was_built"> |
941 | <li tal:condition="context/buildduration"> |
942 | Started <span |
943 | - tal:define="start context/calculated_buildstart" |
944 | + tal:define="start context/date_started" |
945 | tal:attributes="title start/fmt:datetime" |
946 | tal:content="start/fmt:displaydate">2008-01-01</span> |
947 | </li> |
948 | |
949 | === modified file 'lib/lp/soyuz/templates/builds-list.pt' |
950 | --- lib/lp/soyuz/templates/builds-list.pt 2009-11-12 15:12:12 +0000 |
951 | +++ lib/lp/soyuz/templates/builds-list.pt 2010-05-05 15:51:40 +0000 |
952 | @@ -59,9 +59,9 @@ |
953 | <tal:soyuz_record condition="build/buildduration"> |
954 | <span |
955 | tal:attributes=" |
956 | - title build/calculated_buildstart/fmt:datetime" |
957 | + title build/date_started/fmt:datetime" |
958 | tal:content=" |
959 | - build/calculated_buildstart/fmt:displaydate" /> |
960 | + build/date_started/fmt:displaydate" /> |
961 | </tal:soyuz_record> |
962 | <tal:gina_record condition="not: build/buildduration"> |
963 | <i>at an unknown time</i> |
964 | |
965 | === modified file 'lib/lp/soyuz/tests/test_build.py' |
966 | --- lib/lp/soyuz/tests/test_build.py 2010-05-05 15:51:38 +0000 |
967 | +++ lib/lp/soyuz/tests/test_build.py 2010-05-05 15:51:40 +0000 |
968 | @@ -3,8 +3,6 @@ |
969 | |
970 | """Test Build features.""" |
971 | |
972 | -from datetime import datetime, timedelta |
973 | -import pytz |
974 | import unittest |
975 | |
976 | from storm.store import Store |
977 | @@ -13,9 +11,10 @@ |
978 | from canonical.database.constants import UTC_NOW |
979 | from canonical.testing import LaunchpadZopelessLayer |
980 | from lp.services.job.model.job import Job |
981 | -from lp.buildmaster.interfaces.buildbase import BuildStatus, IBuildBase |
982 | +from lp.buildmaster.interfaces.buildbase import BuildStatus |
983 | from lp.buildmaster.interfaces.builder import IBuilderSet |
984 | from lp.buildmaster.interfaces.buildqueue import IBuildQueue |
985 | +from lp.buildmaster.interfaces.packagebuild import IPackageBuild |
986 | from lp.buildmaster.model.buildqueue import BuildQueue |
987 | from lp.soyuz.interfaces.binarypackagebuild import ( |
988 | IBinaryPackageBuild, IBinaryPackageBuildSet) |
989 | @@ -41,19 +40,13 @@ |
990 | spr_only=True, sourcename="gedit", |
991 | status=PackagePublishingStatus.PUBLISHED) |
992 | self.build = gedit_spr.createBuild( |
993 | - distroarchseries=publisher.distroseries['i386'], |
994 | + distro_arch_series=publisher.distroseries['i386'], |
995 | archive=gedit_spr.upload_archive, |
996 | pocket=gedit_spr.package_upload.pocket) |
997 | |
998 | def test_providesInterfaces(self): |
999 | - # Build provides IBuildBase and IBuild. |
1000 | - |
1001 | - # The IBinaryPackageBuild.calculated_buildstart property asserts |
1002 | - # that both datebuilt and buildduration are set. |
1003 | - self.build.datebuilt = datetime.now(pytz.UTC) |
1004 | - self.build.buildduration = timedelta(0, 1) |
1005 | - |
1006 | - self.assertProvides(self.build, IBuildBase) |
1007 | + # Build provides IPackageBuild and IBuild. |
1008 | + self.assertProvides(self.build, IPackageBuild) |
1009 | self.assertProvides(self.build, IBinaryPackageBuild) |
1010 | |
1011 | def test_queueBuild(self): |
1012 | @@ -290,7 +283,8 @@ |
1013 | |
1014 | def testDependencies(self): |
1015 | """Verify that storeBuildInfo sets any dependencies.""" |
1016 | - self.build.storeBuildInfo(self.build, None, {'dependencies': 'somepackage'}) |
1017 | + self.build.storeBuildInfo( |
1018 | + self.build, None, {'dependencies': 'somepackage'}) |
1019 | self.assertIsNot(None, self.build.buildlog) |
1020 | self.assertEqual(self.builder, self.build.builder) |
1021 | self.assertEqual(u'somepackage', self.build.dependencies) |
1022 | |
1023 | === modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py' |
1024 | --- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-05 15:51:38 +0000 |
1025 | +++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-05 15:51:40 +0000 |
1026 | @@ -13,7 +13,6 @@ |
1027 | |
1028 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
1029 | from lp.buildmaster.interfaces.builder import IBuilderSet |
1030 | -from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobDerived |
1031 | from lp.soyuz.interfaces.archive import ArchivePurpose |
1032 | from lp.soyuz.interfaces.buildfarmbuildjob import IBuildFarmBuildJob |
1033 | from lp.soyuz.interfaces.buildpackagejob import IBuildPackageJob |
1034 | @@ -235,6 +234,3 @@ |
1035 | build_farm_job = bq.specific_job |
1036 | self.assertProvides(build_farm_job, IBuildPackageJob) |
1037 | self.assertProvides(build_farm_job, IBuildFarmBuildJob) |
1038 | - self.assertProvides(build_farm_job, IBuildFarmJobDerived) |
1039 | - |
1040 | - |
1041 | |
1042 | === modified file 'lib/lp/translations/configure.zcml' |
1043 | --- lib/lp/translations/configure.zcml 2010-04-22 07:33:12 +0000 |
1044 | +++ lib/lp/translations/configure.zcml 2010-05-05 15:51:40 +0000 |
1045 | @@ -578,9 +578,7 @@ |
1046 | <allow |
1047 | interface="lp.code.interfaces.branchjob.IBranchJob"/> |
1048 | <allow |
1049 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"/> |
1050 | - <allow |
1051 | - interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/> |
1052 | + interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobOld"/> |
1053 | </class> |
1054 | <securedutility |
1055 | component="lp.translations.model.translationtemplatesbuildjob.TranslationTemplatesBuildJob" |
1056 | |
1057 | === modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py' |
1058 | --- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-05 15:51:38 +0000 |
1059 | +++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-05 15:51:40 +0000 |
1060 | @@ -147,7 +147,7 @@ |
1061 | |
1062 | @classmethod |
1063 | def getByJob(cls, job): |
1064 | - """See `IBuildFarmJobDerived`. |
1065 | + """See `IBuildFarmJob`. |
1066 | |
1067 | Overridden here to search via a BranchJob, rather than a Job. |
1068 | """ |
1069 | |
1070 | === modified file 'lib/lp/translations/tests/test_translationtemplatesbuildjob.py' |
1071 | --- lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-05 15:51:38 +0000 |
1072 | +++ lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-05 15:51:40 +0000 |
1073 | @@ -19,7 +19,7 @@ |
1074 | from lp.testing import TestCaseWithFactory |
1075 | |
1076 | from lp.buildmaster.interfaces.buildfarmjob import ( |
1077 | - IBuildFarmJobOld, IBuildFarmJobDerived) |
1078 | + IBuildFarmJobOld) |
1079 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
1080 | from lp.buildmaster.model.buildqueue import BuildQueue |
1081 | from lp.code.interfaces.branch import IBranchSet |
1082 | @@ -54,9 +54,8 @@ |
1083 | |
1084 | def test_new_TranslationTemplatesBuildJob(self): |
1085 | # TranslationTemplateBuildJob implements IBuildFarmJobOld, |
1086 | - # IBuildFarmJobDerived, and IBranchJob. |
1087 | + # and IBranchJob. |
1088 | verifyObject(IBranchJob, self.specific_job) |
1089 | - verifyObject(IBuildFarmJobDerived, self.specific_job) |
1090 | verifyObject(IBuildFarmJobOld, self.specific_job) |
1091 | |
1092 | # Each of these jobs knows the branch it will operate on. |
distro_series should be defined on IPackageBuild, because it's common to all packages, even though the implementation will differ for ISourcePackageR ecipeBuild and IBinaryBuild. If needed, define a property on IPackageBuild that raises NotImplementedE rror.
diff lines 342-343 need to be re-indented.
I'm also concerned about the split between IPackageBuild and IPackageBuildDe rived. It seems like there should only be one interface for things that are "package builds", so please see if you can unify them, or at least make it clear that IPackageBuild only exists to represent the PackageBuild model object.