Merge lp:~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-3 into lp:launchpad/db-devel

Proposed by Michael Nelson
Status: Merged
Merged at revision: 9405
Proposed branch: lp:~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-3
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-2
Diff against target: 786 lines (+263/-94) (has conflicts)
13 files modified
BRANCH.TODO (+4/-0)
lib/lp/buildmaster/doc/buildfarmjob.txt (+8/-5)
lib/lp/buildmaster/interfaces/buildbase.py (+1/-1)
lib/lp/buildmaster/interfaces/packagebuild.py (+32/-0)
lib/lp/buildmaster/model/buildbase.py (+103/-57)
lib/lp/buildmaster/model/buildfarmjob.py (+9/-3)
lib/lp/buildmaster/model/buildfarmjobbehavior.py (+3/-2)
lib/lp/buildmaster/model/packagebuild.py (+53/-9)
lib/lp/buildmaster/tests/test_buildbase.py (+3/-3)
lib/lp/buildmaster/tests/test_packagebuild.py (+19/-6)
lib/lp/code/model/sourcepackagerecipebuild.py (+9/-3)
lib/lp/soyuz/model/buildpackagejob.py (+9/-4)
lib/lp/translations/model/translationtemplatesbuildjob.py (+10/-1)
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-packagebuild-3
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) code* Approve
Review via email: mp+24327@code.launchpad.net

Description of the change

Please read the description of the previous MP at:

https://code.edge.launchpad.net/~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-2/+merge/24211

This branch adds the last three interface methods to IPackageBuild: verifySuccessfulUpload, storeUploadLog and notify, as well as handleStatus() on IPackageBuildDerived (it should not be delegated like the other methods, as it needs to then call sub-handles such as _handleStatus_OK() etc., which need to be called from the top of the chain).

The same tests to run.

The next branch steps back from all this re-shuffling and cleans up the results.

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

Sorry, still haven't sorted out my mailing list subscriptions. I promise I'll do that for the next one and reply inline...

Making the BuildBase methods static is ugly, though I can understand why you're doing it and it seems like a reasonable thing to do for the moment.
Some minor issues:

The various versions of _set_build_farm_job have an extra heading space in their docstring.

The extra_info parameter to IPackageBuild.verify is not documented in its interface.

Also, this code will unfortunately conflict once my simplify-uploadprocess branch lands.

review: Approve (code*)
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

It'd be great if this branch can also use Store.flush rather than flush_database_updates as we discussed on IRC.

Revision history for this message
Michael Nelson (michael.nelson) wrote :

On Thu, Apr 29, 2010 at 3:52 PM, Jelmer Vernooij <email address hidden> wrote:
> Review: Approve code*
> Sorry, still haven't sorted out my mailing list subscriptions. I promise I'll do that for the next one and reply inline...
>
> Making the BuildBase methods static is ugly, though I can understand why you're doing it and it seems like a reasonable thing to do for the moment.

Yep - it's temporary just so there's only one implementation while I
keep refactoring (and tests continue to pass). I've updated the
BRANCH.TODO to reflect that (which will ensure the code doesn't land
until it is fixed).

> Some minor issues:
>
> The various versions of _set_build_farm_job have an extra heading space in their docstring.

Fixed.

>
> The extra_info parameter to IPackageBuild.verify is not documented in its interface.

Fixed.

>
> Also, this code will unfortunately conflict once my simplify-uploadprocess branch lands.

Yeah, that's ok. I'm expecting to be resolving conflicts for the next while :)

Incremental diff attached. And I'd already replaced
flush_database_updates as discussed in a previous rev.

Thanks!

=== modified file 'BRANCH.TODO'
--- BRANCH.TODO 2010-04-13 19:17:03 +0000
+++ BRANCH.TODO 2010-04-29 15:10:20 +0000
@@ -2,3 +2,7 @@
2# landing. There is a test to ensure it is empty in trunk. If there is2# landing. There is a test to ensure it is empty in trunk. If there is
3# stuff still here when you are ready to land, the items should probably3# stuff still here when you are ready to land, the items should probably
4# be converted to bugs so they can be scheduled.4# be converted to bugs so they can be scheduled.
5
6The static methods on IBuildFarmJob/IPackageBuild should be reverted
7to normal methods once all *Build classes have transitioned to the new
8model and IBuildBase is removed.
59
=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-04-29 10:56:03 +0000
+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-04-29 15:18:45 +0000
@@ -130,7 +130,13 @@
130 """130 """
131131
132 def notify(extra_info=None):132 def notify(extra_info=None):
133 """Notify current build state to related people via email."""133 """Notify current build state to related people via email.
134
135 :param extra_info: Optional extra information that will be included
136 in the notification email. If the notification is for a
137 failed-to-upload error then this must be the content of the
138 upload log.
139 """
134140
135141
136class IPackageBuildSource(Interface):142class IPackageBuildSource(Interface):
137143
=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
--- lib/lp/code/model/sourcepackagerecipebuild.py 2010-04-28 08:32:10 +0000
+++ lib/lp/code/model/sourcepackagerecipebuild.py 2010-04-29 15:10:58 +0000
@@ -223,7 +223,7 @@
223 super(SourcePackageRecipeBuildJob, self).__init__()223 super(SourcePackageRecipeBuildJob, self).__init__()
224224
225 def _set_build_farm_job(self):225 def _set_build_farm_job(self):
226 """ Setup the IBuildFarmJob delegate.226 """Setup the IBuildFarmJob delegate.
227227
228 We override this to provide a delegate specific to package builds."""228 We override this to provide a delegate specific to package builds."""
229 self.build_farm_job = PackageBuild(self.build)229 self.build_farm_job = PackageBuild(self.build)
230230
=== modified file 'lib/lp/soyuz/model/buildpackagejob.py'
--- lib/lp/soyuz/model/buildpackagejob.py 2010-04-28 08:32:10 +0000
+++ lib/lp/soyuz/model/buildpackagejob.py 2010-04-29 15:11:32 +0000
@@ -46,7 +46,7 @@
46 super(BuildPackageJob, self).__init__()46 super(BuildPackageJob, self).__init__()
4747
48 def _set_build_farm_job(self):48 def _set_build_farm_job(self):
49 """ Setup the IBuildFarmJob delegate.49 """Setup the IBuildFarmJob delegate.
5050
51 We override this to provide a delegate specific to package builds."""51 We override this to provide a delegate specific to package builds."""
52 self.build_farm_job = PackageBuild(self.build)52 self.build_farm_job = PackageBuild(self.build)
5353
=== modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py'
--- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-04-28 10:59:12 +0000
+++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-04-29 15:11:07 +0000
@@ -49,7 +49,7 @@
49 super(TranslationTemplatesBuildJob, self).__init__(branch_job)49 super(TranslationTemplatesBuildJob, self).__init__(branch_job)
5050
51 def _set_build_farm_job(self):51 def _set_build_farm_job(self):
52 """ Setup the IBuildFarmJob delegate.52 """Setup the IBuildFarmJob delegate.
5353
54 We override this to provide a non-database delegate that simply54 We override this to provide a non-database delegate that simply
55 provides required functionality to the queue system."""55 provides required functionality to the queue system."""

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'BRANCH.TODO'
--- BRANCH.TODO 2010-04-13 19:17:03 +0000
+++ BRANCH.TODO 2010-05-05 15:49:24 +0000
@@ -2,3 +2,7 @@
2# landing. There is a test to ensure it is empty in trunk. If there is2# landing. There is a test to ensure it is empty in trunk. If there is
3# stuff still here when you are ready to land, the items should probably3# stuff still here when you are ready to land, the items should probably
4# be converted to bugs so they can be scheduled.4# be converted to bugs so they can be scheduled.
5
6The static methods on IBuildFarmJob/IPackageBuild should be reverted
7to normal methods once all *Build classes have transitioned to the new
8model and IBuildBase is removed.
59
=== modified file 'lib/lp/buildmaster/doc/buildfarmjob.txt'
--- lib/lp/buildmaster/doc/buildfarmjob.txt 2010-04-16 14:37:33 +0000
+++ lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-05 15:49:24 +0000
@@ -1,7 +1,8 @@
1BuildFarmJob1BuildFarmJob
2============2============
33
4 >>> from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob4 >>> from lp.buildmaster.interfaces.buildfarmjob import (
5 ... BuildFarmJobType, IBuildFarmJob)
5 >>> from lp.buildmaster.model.buildfarmjob import (6 >>> from lp.buildmaster.model.buildfarmjob import (
6 ... BuildFarmJob, BuildFarmJobDerived)7 ... BuildFarmJob, BuildFarmJobDerived)
78
@@ -9,12 +10,14 @@
9specific build farm job classes will automatically delegate to10specific build farm job classes will automatically delegate to
10BuildFarmJob by inheriting BuildFarmJobDerived.11BuildFarmJob by inheriting BuildFarmJobDerived.
1112
12 >>> buildfarmjob = BuildFarmJob()13 >>> buildfarmjob = BuildFarmJob(BuildFarmJobType.PACKAGEBUILD)
13 >>> verifyObject(IBuildFarmJob, buildfarmjob)14 >>> verifyObject(IBuildFarmJob, buildfarmjob)
14 True15 True
1516
16The BuildFarmJob class does not (yet) do a lot itself, other than17The BuildFarmJob class provides many of the common attributes used by
17providing default implementations for its methods.18different types of build farm jobs, as well as default implementations
19for the common methods. The BuildFarmJob class provides default
20implementations for many build-related methods.
1821
19 >>> print buildfarmjob.getLogFileName()22 >>> print buildfarmjob.getLogFileName()
20 buildlog.txt23 buildlog.txt
@@ -24,6 +27,7 @@
24 ...27 ...
25 NotImplementedError28 NotImplementedError
2629
30For more details, please refer to lp.buildmaster.tests.test_buildfarmjob.
2731
28BuildFarmJobDerived32BuildFarmJobDerived
29===================33===================
@@ -40,4 +44,3 @@
40instance of a specific build-farm job implementation associated with a44instance of a specific build-farm job implementation associated with a
41given Job instance which must be called in the context of a concrete45given Job instance which must be called in the context of a concrete
42derived class. See lp.buildmaster.tests.test_buildqueue for examples.46derived class. See lp.buildmaster.tests.test_buildqueue for examples.
43
4447
=== modified file 'lib/lp/buildmaster/interfaces/buildbase.py'
--- lib/lp/buildmaster/interfaces/buildbase.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/interfaces/buildbase.py 2010-05-05 15:49:24 +0000
@@ -228,7 +228,7 @@
228>>>>>>> MERGE-SOURCE228>>>>>>> MERGE-SOURCE
229 """229 """
230230
231 def handleStatus(status, librarian, slave_status):231 def handleStatus(build, status, librarian, slave_status):
232 """Handle a finished build status from a slave.232 """Handle a finished build status from a slave.
233233
234 :param status: Slave build status string with 'BuildStatus.' stripped.234 :param status: Slave build status string with 'BuildStatus.' stripped.
235235
=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:49:24 +0000
@@ -6,6 +6,7 @@
6__all__ = [6__all__ = [
7 'IPackageBuild',7 'IPackageBuild',
8 'IPackageBuildSource',8 'IPackageBuildSource',
9 'IPackageBuildDerived',
9 ]10 ]
1011
1112
@@ -118,6 +119,25 @@
118 custom status handlers, but it should not be called externally.119 custom status handlers, but it should not be called externally.
119 """120 """
120121
122 def verifySuccessfulUpload():
123 """Verify that the upload of this build completed succesfully."""
124
125 def storeUploadLog(content):
126 """Store the given content as the build upload_log.
127
128 :param content: string containing the upload-processor log output for
129 the binaries created in this build.
130 """
131
132 def notify(extra_info=None):
133 """Notify current build state to related people via email.
134
135 :param extra_info: Optional extra information that will be included
136 in the notification email. If the notification is for a
137 failed-to-upload error then this must be the content of the
138 upload log.
139 """
140
121141
122class IPackageBuildSource(Interface):142class IPackageBuildSource(Interface):
123 """A utility of this interface used to create _things_."""143 """A utility of this interface used to create _things_."""
@@ -129,3 +149,15 @@
129 :param pocket: An item of `PackagePublishingPocket`.149 :param pocket: An item of `PackagePublishingPocket`.
130 :param dependencies: An optional debian-like dependency line.150 :param dependencies: An optional debian-like dependency line.
131 """151 """
152
153
154class IPackageBuildDerived(Interface):
155 """Classes deriving from IPackageBuild inherit the default handleStatus.
156 """
157 def handleStatus(status, librarian, slave_status):
158 """Handle a finished build status from a slave.
159
160 :param status: Slave build status string with 'BuildStatus.' stripped.
161 :param slave_status: A dict as returned by IBuilder.slaveStatus
162 """
163
132164
=== modified file 'lib/lp/buildmaster/model/buildbase.py'
--- lib/lp/buildmaster/model/buildbase.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/model/buildbase.py 2010-05-05 15:49:24 +0000
@@ -125,20 +125,31 @@
125 return None125 return None
126 return self._getProxiedFileURL(self.upload_log)126 return self._getProxiedFileURL(self.upload_log)
127127
128 def handleStatus(self, status, librarian, slave_status):128 @staticmethod
129 def handleStatus(build, status, librarian, slave_status):
129 """See `IBuildBase`."""130 """See `IBuildBase`."""
130 logger = logging.getLogger(BUILDD_MANAGER_LOG_NAME)131 logger = logging.getLogger(BUILDD_MANAGER_LOG_NAME)
131132
132 method = getattr(self, '_handleStatus_' + status, None)133 method = getattr(build, '_handleStatus_' + status, None)
133134
134 if method is None:135 if method is None:
136<<<<<<< TREE
135 logger.critical("Unknown BuildStatus '%s' for builder '%s'"137 logger.critical("Unknown BuildStatus '%s' for builder '%s'"
136 % (status, self.buildqueue_record.builder.url))138 % (status, self.buildqueue_record.builder.url))
139=======
140 if build.buildqueue_record is not None:
141 logger.critical("Unknown BuildStatus '%s' for builder '%s'"
142 % (status, build.buildqueue_record.builder.url))
143 else:
144 logger.critical("Unknown BuildStatus '%s' for %r"
145 % (status, build))
146>>>>>>> MERGE-SOURCE
137 return147 return
138148
139 method(librarian, slave_status, logger)149 method(build, librarian, slave_status, logger)
140150
141<<<<<<< TREE151<<<<<<< TREE
152 def _handleStatus_OK(self, librarian, slave_status, logger):
142=======153=======
143 def processUpload(self, leaf, root, logger):154 def processUpload(self, leaf, root, logger):
144 """Process an upload.155 """Process an upload.
@@ -168,8 +179,9 @@
168 ztm=ZopelessTransactionManager, log=logger)179 ztm=ZopelessTransactionManager, log=logger)
169 processor.processUploadQueue(leaf)180 processor.processUploadQueue(leaf)
170181
182 @staticmethod
183 def _handleStatus_OK(build, librarian, slave_status, logger):
171>>>>>>> MERGE-SOURCE184>>>>>>> MERGE-SOURCE
172 def _handleStatus_OK(self, librarian, slave_status, logger):
173 """Handle a package that built successfully.185 """Handle a package that built successfully.
174186
175 Once built successfully, we pull the files, store them in a187 Once built successfully, we pull the files, store them in a
@@ -179,36 +191,41 @@
179 filemap = slave_status['filemap']191 filemap = slave_status['filemap']
180192
181 logger.info("Processing successful build %s from builder %s" % (193 logger.info("Processing successful build %s from builder %s" % (
182 self.buildqueue_record.specific_job.build.title,194 build.buildqueue_record.specific_job.build.title,
183 self.buildqueue_record.builder.name))195 build.buildqueue_record.builder.name))
184 # Explode before collect a binary that is denied in this196 # Explode before collect a binary that is denied in this
185 # distroseries/pocket197 # distroseries/pocket
186 if not self.archive.allowUpdatesToReleasePocket():198 if not build.archive.allowUpdatesToReleasePocket():
187 assert self.distroseries.canUploadToPocket(self.pocket), (199 assert build.distroseries.canUploadToPocket(build.pocket), (
188 "%s (%s) can not be built for pocket %s: illegal status"200 "%s (%s) can not be built for pocket %s: illegal status"
189 % (self.title, self.id, self.pocket.name))201 % (build.title, build.id, build.pocket.name))
190202
191 # ensure we have the correct build root as:203 # ensure we have the correct build root as:
192 # <BUILDMASTER_ROOT>/incoming/<UPLOAD_LEAF>/<TARGET_PATH>/[FILES]204 # <BUILDMASTER_ROOT>/incoming/<UPLOAD_LEAF>/<TARGET_PATH>/[FILES]
193 root = os.path.abspath(config.builddmaster.root)205 root = os.path.abspath(config.builddmaster.root)
194206
195 # create a single directory to store build result files207 # create a single directory to store build result files
196 upload_leaf = self.getUploadDirLeaf(208 upload_leaf = build.getUploadDirLeaf(
197 '%s-%s' % (self.id, self.buildqueue_record.id))209 '%s-%s' % (build.id, build.buildqueue_record.id))
198 upload_dir = self.getUploadDir(upload_leaf)210 upload_dir = build.getUploadDir(upload_leaf)
199 logger.debug("Storing build result at '%s'" % upload_dir)211 logger.debug("Storing build result at '%s'" % upload_dir)
200212
201 # Build the right UPLOAD_PATH so the distribution and archive213 # Build the right UPLOAD_PATH so the distribution and archive
202 # can be correctly found during the upload:214 # can be correctly found during the upload:
203 # <archive_id>/distribution_name215 # <archive_id>/distribution_name
204 # for all destination archive types.216 # for all destination archive types.
217<<<<<<< TREE
205 archive = self.archive218 archive = self.archive
206 distribution_name = self.distribution.name219 distribution_name = self.distribution.name
207 target_path = '%s/%s' % (archive.id, distribution_name)220 target_path = '%s/%s' % (archive.id, distribution_name)
208 upload_path = os.path.join(upload_dir, target_path)221 upload_path = os.path.join(upload_dir, target_path)
222=======
223 upload_path = os.path.join(upload_dir, str(build.archive.id),
224 build.distribution.name)
225>>>>>>> MERGE-SOURCE
209 os.makedirs(upload_path)226 os.makedirs(upload_path)
210227
211 slave = removeSecurityProxy(self.buildqueue_record.builder.slave)228 slave = removeSecurityProxy(build.buildqueue_record.builder.slave)
212 successful_copy_from_slave = True229 successful_copy_from_slave = True
213 for filename in filemap:230 for filename in filemap:
214 logger.info("Grabbing file: %s" % filename)231 logger.info("Grabbing file: %s" % filename)
@@ -220,7 +237,7 @@
220 successful_copy_from_slave = False237 successful_copy_from_slave = False
221 logger.warning(238 logger.warning(
222 "A slave tried to upload the file '%s' "239 "A slave tried to upload the file '%s' "
223 "for the build %d." % (filename, self.id))240 "for the build %d." % (filename, build.id))
224 break241 break
225 out_file = open(out_file_name, "wb")242 out_file = open(out_file_name, "wb")
226 slave_file = slave.getFile(filemap[filename])243 slave_file = slave.getFile(filemap[filename])
@@ -229,6 +246,7 @@
229 # We only attempt the upload if we successfully copied all the246 # We only attempt the upload if we successfully copied all the
230 # files from the slave.247 # files from the slave.
231 if successful_copy_from_slave:248 if successful_copy_from_slave:
249<<<<<<< TREE
232 uploader_logfilename = os.path.join(250 uploader_logfilename = os.path.join(
233 upload_dir, UPLOAD_LOG_FILENAME)251 upload_dir, UPLOAD_LOG_FILENAME)
234 uploader_command = self.getUploaderCommand(252 uploader_command = self.getUploaderCommand(
@@ -251,6 +269,14 @@
251 # to not return error, it only happen when the code is broken).269 # to not return error, it only happen when the code is broken).
252 uploader_result_code = uploader_process.returncode270 uploader_result_code = uploader_process.returncode
253 logger.info("Uploader returned %d" % uploader_result_code)271 logger.info("Uploader returned %d" % uploader_result_code)
272=======
273 logger.info("Invoking uploader on %s for %s" % (root, upload_leaf))
274 upload_logger = BufferLogger()
275 upload_log = build.processUpload(upload_leaf, root, upload_logger)
276 uploader_log_content = upload_logger.buffer.getvalue()
277 else:
278 uploader_log_content = 'Copy from slave was unsuccessful.'
279>>>>>>> MERGE-SOURCE
254280
255 # Quick and dirty hack to carry on on process-upload failures281 # Quick and dirty hack to carry on on process-upload failures
256 if os.path.exists(upload_dir):282 if os.path.exists(upload_dir):
@@ -290,7 +316,7 @@
290316
291 # Store build information, build record was already updated during317 # Store build information, build record was already updated during
292 # the binary upload.318 # the binary upload.
293 self.storeBuildInfo(self, librarian, slave_status)319 build.storeBuildInfo(build, librarian, slave_status)
294320
295 # Retrive the up-to-date build record and perform consistency321 # Retrive the up-to-date build record and perform consistency
296 # checks. The build record should be updated during the binary322 # checks. The build record should be updated during the binary
@@ -305,56 +331,65 @@
305 # uploader about this occurrence. The failure notification will331 # uploader about this occurrence. The failure notification will
306 # also contain the information required to manually reprocess the332 # also contain the information required to manually reprocess the
307 # binary upload when it was the case.333 # binary upload when it was the case.
308 if (self.buildstate != BuildStatus.FULLYBUILT or334 if (build.buildstate != BuildStatus.FULLYBUILT or
309 not successful_copy_from_slave or335 not successful_copy_from_slave or
336<<<<<<< TREE
310 not self.verifySuccessfulUpload()):337 not self.verifySuccessfulUpload()):
311 logger.warning("Build %s upload failed." % self.id)338 logger.warning("Build %s upload failed." % self.id)
312 self.buildstate = BuildStatus.FAILEDTOUPLOAD339 self.buildstate = BuildStatus.FAILEDTOUPLOAD
313 uploader_log_content = self.getUploadLogContent(root,340 uploader_log_content = self.getUploadLogContent(root,
314 upload_leaf)341 upload_leaf)
342=======
343 not build.verifySuccessfulUpload()):
344 logger.warning("Build %s upload failed." % build.id)
345 build.buildstate = BuildStatus.FAILEDTOUPLOAD
346>>>>>>> MERGE-SOURCE
315 # Store the upload_log_contents in librarian so it can be347 # Store the upload_log_contents in librarian so it can be
316 # accessed by anyone with permission to see the build.348 # accessed by anyone with permission to see the build.
317 self.storeUploadLog(uploader_log_content)349 build.storeUploadLog(uploader_log_content)
318 # Notify the build failure.350 # Notify the build failure.
319 self.notify(extra_info=uploader_log_content)351 build.notify(extra_info=uploader_log_content)
320 else:352 else:
321 logger.info(353 logger.info(
322 "Gathered %s %d completely" % (354 "Gathered %s %d completely" % (
323 self.__class__.__name__, self.id))355 build.__class__.__name__, build.id))
324356
325 # Release the builder for another job.357 # Release the builder for another job.
326 self.buildqueue_record.builder.cleanSlave()358 build.buildqueue_record.builder.cleanSlave()
327 # Remove BuildQueue record.359 # Remove BuildQueue record.
328 self.buildqueue_record.destroySelf()360 build.buildqueue_record.destroySelf()
329361
330 def _handleStatus_PACKAGEFAIL(self, librarian, slave_status, logger):362 @staticmethod
363 def _handleStatus_PACKAGEFAIL(build, librarian, slave_status, logger):
331 """Handle a package that had failed to build.364 """Handle a package that had failed to build.
332365
333 Build has failed when trying the work with the target package,366 Build has failed when trying the work with the target package,
334 set the job status as FAILEDTOBUILD, store available info and367 set the job status as FAILEDTOBUILD, store available info and
335 remove Buildqueue entry.368 remove Buildqueue entry.
336 """369 """
337 self.buildstate = BuildStatus.FAILEDTOBUILD370 build.buildstate = BuildStatus.FAILEDTOBUILD
338 self.storeBuildInfo(self, librarian, slave_status)371 build.storeBuildInfo(build, librarian, slave_status)
339 self.buildqueue_record.builder.cleanSlave()372 build.buildqueue_record.builder.cleanSlave()
340 self.notify()373 build.notify()
341 self.buildqueue_record.destroySelf()374 build.buildqueue_record.destroySelf()
342375
343 def _handleStatus_DEPFAIL(self, librarian, slave_status, logger):376 @staticmethod
377 def _handleStatus_DEPFAIL(build, librarian, slave_status, logger):
344 """Handle a package that had missing dependencies.378 """Handle a package that had missing dependencies.
345379
346 Build has failed by missing dependencies, set the job status as380 Build has failed by missing dependencies, set the job status as
347 MANUALDEPWAIT, store available information, remove BuildQueue381 MANUALDEPWAIT, store available information, remove BuildQueue
348 entry and release builder slave for another job.382 entry and release builder slave for another job.
349 """383 """
350 self.buildstate = BuildStatus.MANUALDEPWAIT384 build.buildstate = BuildStatus.MANUALDEPWAIT
351 self.storeBuildInfo(self, librarian, slave_status)385 build.storeBuildInfo(build, librarian, slave_status)
352 logger.critical("***** %s is MANUALDEPWAIT *****"386 logger.critical("***** %s is MANUALDEPWAIT *****"
353 % self.buildqueue_record.builder.name)387 % build.buildqueue_record.builder.name)
354 self.buildqueue_record.builder.cleanSlave()388 build.buildqueue_record.builder.cleanSlave()
355 self.buildqueue_record.destroySelf()389 build.buildqueue_record.destroySelf()
356390
357 def _handleStatus_CHROOTFAIL(self, librarian, slave_status,391 @staticmethod
392 def _handleStatus_CHROOTFAIL(build, librarian, slave_status,
358 logger):393 logger):
359 """Handle a package that had failed when unpacking the CHROOT.394 """Handle a package that had failed when unpacking the CHROOT.
360395
@@ -362,15 +397,16 @@
362 job as CHROOTFAIL, store available information, remove BuildQueue397 job as CHROOTFAIL, store available information, remove BuildQueue
363 and release the builder.398 and release the builder.
364 """399 """
365 self.buildstate = BuildStatus.CHROOTWAIT400 build.buildstate = BuildStatus.CHROOTWAIT
366 self.storeBuildInfo(self, librarian, slave_status)401 build.storeBuildInfo(build, librarian, slave_status)
367 logger.critical("***** %s is CHROOTWAIT *****" %402 logger.critical("***** %s is CHROOTWAIT *****" %
368 self.buildqueue_record.builder.name)403 build.buildqueue_record.builder.name)
369 self.buildqueue_record.builder.cleanSlave()404 build.buildqueue_record.builder.cleanSlave()
370 self.notify()405 build.notify()
371 self.buildqueue_record.destroySelf()406 build.buildqueue_record.destroySelf()
372407
373 def _handleStatus_BUILDERFAIL(self, librarian, slave_status, logger):408 @staticmethod
409 def _handleStatus_BUILDERFAIL(build, librarian, slave_status, logger):
374 """Handle builder failures.410 """Handle builder failures.
375411
376 Build has been failed when trying to build the target package,412 Build has been failed when trying to build the target package,
@@ -378,14 +414,15 @@
378 and 'clean' the builder to do another jobs.414 and 'clean' the builder to do another jobs.
379 """415 """
380 logger.warning("***** %s has failed *****"416 logger.warning("***** %s has failed *****"
381 % self.buildqueue_record.builder.name)417 % build.buildqueue_record.builder.name)
382 self.buildqueue_record.builder.failBuilder(418 build.buildqueue_record.builder.failBuilder(
383 "Builder returned BUILDERFAIL when asked for its status")419 "Builder returned BUILDERFAIL when asked for its status")
384 # simply reset job420 # simply reset job
385 self.storeBuildInfo(self, librarian, slave_status)421 build.storeBuildInfo(build, librarian, slave_status)
386 self.buildqueue_record.reset()422 build.buildqueue_record.reset()
387423
388 def _handleStatus_GIVENBACK(self, librarian, slave_status, logger):424 @staticmethod
425 def _handleStatus_GIVENBACK(build, librarian, slave_status, logger):
389 """Handle automatic retry requested by builder.426 """Handle automatic retry requested by builder.
390427
391 GIVENBACK pseudo-state represents a request for automatic retry428 GIVENBACK pseudo-state represents a request for automatic retry
@@ -393,15 +430,15 @@
393 ZERO.430 ZERO.
394 """431 """
395 logger.warning("***** %s is GIVENBACK by %s *****"432 logger.warning("***** %s is GIVENBACK by %s *****"
396 % (self.buildqueue_record.specific_job.build.title,433 % (build.buildqueue_record.specific_job.build.title,
397 self.buildqueue_record.builder.name))434 build.buildqueue_record.builder.name))
398 self.storeBuildInfo(self, librarian, slave_status)435 build.storeBuildInfo(build, librarian, slave_status)
399 # XXX cprov 2006-05-30: Currently this information is not436 # XXX cprov 2006-05-30: Currently this information is not
400 # properly presented in the Web UI. We will discuss it in437 # properly presented in the Web UI. We will discuss it in
401 # the next Paris Summit, infinity has some ideas about how438 # the next Paris Summit, infinity has some ideas about how
402 # to use this content. For now we just ensure it's stored.439 # to use this content. For now we just ensure it's stored.
403 self.buildqueue_record.builder.cleanSlave()440 build.buildqueue_record.builder.cleanSlave()
404 self.buildqueue_record.reset()441 build.buildqueue_record.reset()
405442
406 @staticmethod443 @staticmethod
407 def getLogFromSlave(build):444 def getLogFromSlave(build):
@@ -428,25 +465,34 @@
428 else:465 else:
429 build.dependencies = None466 build.dependencies = None
430467
431 def storeUploadLog(self, content):468 @staticmethod
432 """See `IBuildBase`."""469 def createUploadLog(build, content, filename=None):
470 """Creates a file on the librarian for the upload log.
471
472 :return: ILibraryFileAlias for the upload log file.
473 """
433 # The given content is stored in the librarian, restricted as474 # The given content is stored in the librarian, restricted as
434 # necessary according to the targeted archive's privacy. The content475 # necessary according to the targeted archive's privacy. The content
435 # object's 'upload_log' attribute will point to the476 # object's 'upload_log' attribute will point to the
436 # `LibrarianFileAlias`.477 # `LibrarianFileAlias`.
437478
438 assert self.upload_log is None, (479 assert build.upload_log is None, (
439 "Upload log information already exists and cannot be overridden.")480 "Upload log information already exists and cannot be overridden.")
440481
441 filename = 'upload_%s_log.txt' % self.id482 if filename is None:
483 filename = 'upload_%s_log.txt' % build.id
442 contentType = filenameToContentType(filename)484 contentType = filenameToContentType(filename)
443 file_size = len(content)485 file_size = len(content)
444 file_content = StringIO(content)486 file_content = StringIO(content)
445 restricted = self.is_private487 restricted = build.is_private
446488
447 library_file = getUtility(ILibraryFileAliasSet).create(489 return getUtility(ILibraryFileAliasSet).create(
448 filename, file_size, file_content, contentType=contentType,490 filename, file_size, file_content, contentType=contentType,
449 restricted=restricted)491 restricted=restricted)
492
493 def storeUploadLog(self, content):
494 """See `IBuildBase`."""
495 library_file = self.createUploadLog(self, content)
450 self.upload_log = library_file496 self.upload_log = library_file
451497
452 def queueBuild(self, suspended=False):498 def queueBuild(self, suspended=False):
453499
=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
--- lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:49:24 +0000
@@ -201,9 +201,15 @@
201 self._set_build_farm_job()201 self._set_build_farm_job()
202202
203 def _set_build_farm_job(self):203 def _set_build_farm_job(self):
204 """Set the build farm job to which we will delegate.204 """Set the default build farm job to which we will delegate.
205205
206 Sub-classes can override as required.206 Sub-classes should override as required.
207
208 XXX 2010-04-27 michael.nelson bug=570939
209 This only exists because certain classes assume that
210 BuildFarmJob/PackageBuild are in-memory objects that simply
211 provide methods to update the associated builds.
212 We can remove it once the above bug is completed.
207 """213 """
208 self.build_farm_job = BuildFarmJob(214 self.build_farm_job = BuildFarmJob(
209 job_type=BuildFarmJobType.PACKAGEBUILD)215 job_type=BuildFarmJobType.PACKAGEBUILD)
210216
=== modified file 'lib/lp/buildmaster/model/buildfarmjobbehavior.py'
--- lib/lp/buildmaster/model/buildfarmjobbehavior.py 2010-04-12 16:23:13 +0000
+++ lib/lp/buildmaster/model/buildfarmjobbehavior.py 2010-05-05 15:49:24 +0000
@@ -183,8 +183,9 @@
183183
184 # XXX: dsilvers 2005-03-02: Confirm the builder has the right build?184 # XXX: dsilvers 2005-03-02: Confirm the builder has the right build?
185185
186 queueItem.specific_job.build.handleStatus(186 build = queueItem.specific_job.build
187 build_status, librarian, slave_status)187 build.handleStatus(
188 build, build_status, librarian, slave_status)
188189
189190
190class IdleBuildBehavior(BuildFarmJobBehaviorBase):191class IdleBuildBehavior(BuildFarmJobBehaviorBase):
191192
=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
--- lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:49:24 +0000
@@ -22,7 +22,7 @@
22from lp.buildmaster.interfaces.buildbase import BuildStatus22from lp.buildmaster.interfaces.buildbase import BuildStatus
23from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource23from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
24from lp.buildmaster.interfaces.packagebuild import (24from lp.buildmaster.interfaces.packagebuild import (
25 IPackageBuild, IPackageBuildSource)25 IPackageBuild, IPackageBuildDerived, IPackageBuildSource)
26from lp.buildmaster.model.buildbase import BuildBase26from lp.buildmaster.model.buildbase import BuildBase
27from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived27from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
28from lp.registry.interfaces.pocket import PackagePublishingPocket28from lp.registry.interfaces.pocket import PackagePublishingPocket
@@ -62,7 +62,7 @@
62 def __init__(self, build):62 def __init__(self, build):
63 """Construct a PackageBuild.63 """Construct a PackageBuild.
6464
65 XXX 2010-04-21 michael.nelson bug=53670065 XXX 2010-04-21 michael.nelson bug=570939
66 This initialiser is only used by IBuildFarmJobDerived classes66 This initialiser is only used by IBuildFarmJobDerived classes
67 that are not yet expecting a concrete BuildFarmJob (and so are67 that are not yet expecting a concrete BuildFarmJob (and so are
68 expecting to pass in the build to which they refer, such as68 expecting to pass in the build to which they refer, such as
@@ -196,10 +196,54 @@
196 """See `IPackageBuild`."""196 """See `IPackageBuild`."""
197 return BuildBase.storeBuildInfo(self, librarian, slave_status)197 return BuildBase.storeBuildInfo(self, librarian, slave_status)
198198
199199 def verifySuccessfulUpload(self):
200class PackageBuildDerived(BuildFarmJobDerived):200 """See `IPackageBuild`."""
201 """Override the base delegate to use a build farm job specific to201 raise NotImplementedError
202 packages.202
203 """203 def storeUploadLog(self, content):
204 def _set_build_farm_job(self):204 """See `IPackageBuild`."""
205 self.build_farm_job = PackageBuild(self.build)205 filename = "upload_%s_log.txt" % self.build_farm_job.id
206 library_file = BuildBase.createUploadLog(
207 self, content, filename=filename)
208 self.upload_log = library_file
209
210 def notify(self, extra_info=None):
211 """See `IPackageBuild`."""
212 raise NotImplementedError
213
214
215class PackageBuildDerived:
216 """See `IPackageBuildDerived`."""
217 implements(IPackageBuildDerived)
218
219 def handleStatus(self, status, librarian, slave_status):
220 """See `IPackageBuildDerived`."""
221 return BuildBase.handleStatus(self, status, librarian, slave_status)
222
223 # The following private handlers currently re-use the BuildBase
224 # implementation until it is no longer in use. If we find in the
225 # future that it would be useful to delegate these also, they can be
226 # added to IBuildFarmJob or IPackageBuild as necessary.
227 def _handleStatus_OK(self, librarian, slave_status, logger):
228 return BuildBase._handleStatus_OK(
229 self, librarian, slave_status, logger)
230
231 def _handleStatus_PACKAGEFAIL(self, librarian, slave_status, logger):
232 return BuildBase._handleStatus_PACKAGEFAIL(
233 self, librarian, slave_status, logger)
234
235 def _handleStatus_DEPFAIL(self, librarian, slave_status, logger):
236 return BuildBase._handleStatus_DEPFAIL(
237 self, librarian, slave_status, logger)
238
239 def _handleStatus_CHROOTFAIL(self, librarian, slave_status, logger):
240 return BuildBase._handleStatus_CHROOTFAIL(
241 self, librarian, slave_status, logger)
242
243 def _handleStatus_BUILDERFAIL(self, librarian, slave_status, logger):
244 return BuildBase._handleStatus_BUILDERFAIL(
245 self, librarian, slave_status, logger)
246
247 def _handleStatus_GIVENBACK(self, librarian, slave_status, logger):
248 return BuildBase._handleStatus_GIVENBACK(
249 self, librarian, slave_status, logger)
206250
=== modified file 'lib/lp/buildmaster/tests/test_buildbase.py'
--- lib/lp/buildmaster/tests/test_buildbase.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/tests/test_buildbase.py 2010-05-05 15:49:24 +0000
@@ -192,7 +192,7 @@
192 # A filemap with plain filenames should not cause a problem.192 # A filemap with plain filenames should not cause a problem.
193 # The call to handleStatus will attempt to get the file from193 # The call to handleStatus will attempt to get the file from
194 # the slave resulting in a URL error in this test case.194 # the slave resulting in a URL error in this test case.
195 self.build.handleStatus('OK', None, {195 self.build.handleStatus(self.build, 'OK', None, {
196 'filemap': { 'myfile.py': 'test_file_hash'},196 'filemap': { 'myfile.py': 'test_file_hash'},
197 })197 })
198198
@@ -202,7 +202,7 @@
202 def test_handleStatus_OK_absolute_filepath(self):202 def test_handleStatus_OK_absolute_filepath(self):
203 # A filemap that tries to write to files outside of203 # A filemap that tries to write to files outside of
204 # the upload directory will result in a failed upload.204 # the upload directory will result in a failed upload.
205 self.build.handleStatus('OK', None, {205 self.build.handleStatus(self.build, 'OK', None, {
206 'filemap': { '/tmp/myfile.py': 'test_file_hash'},206 'filemap': { '/tmp/myfile.py': 'test_file_hash'},
207 })207 })
208 self.assertEqual(BuildStatus.FAILEDTOUPLOAD, self.build.buildstate)208 self.assertEqual(BuildStatus.FAILEDTOUPLOAD, self.build.buildstate)
@@ -211,7 +211,7 @@
211 def test_handleStatus_OK_relative_filepath(self):211 def test_handleStatus_OK_relative_filepath(self):
212 # A filemap that tries to write to files outside of212 # A filemap that tries to write to files outside of
213 # the upload directory will result in a failed upload.213 # the upload directory will result in a failed upload.
214 self.build.handleStatus('OK', None, {214 self.build.handleStatus(self.build, 'OK', None, {
215 'filemap': { '../myfile.py': 'test_file_hash'},215 'filemap': { '../myfile.py': 'test_file_hash'},
216 })216 })
217 self.assertEqual(BuildStatus.FAILEDTOUPLOAD, self.build.buildstate)217 self.assertEqual(BuildStatus.FAILEDTOUPLOAD, self.build.buildstate)
218218
=== modified file 'lib/lp/buildmaster/tests/test_packagebuild.py'
--- lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:49:22 +0000
+++ lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:49:24 +0000
@@ -6,12 +6,12 @@
6__metaclass__ = type6__metaclass__ = type
77
8import unittest8import unittest
9import hashlib
910
10from storm.store import Store11from storm.store import Store
11from zope.component import getUtility12from zope.component import getUtility
12from zope.security.proxy import removeSecurityProxy13from zope.security.proxy import removeSecurityProxy
1314
14from canonical.database.sqlbase import flush_database_updates
15from canonical.testing.layers import LaunchpadFunctionalLayer15from canonical.testing.layers import LaunchpadFunctionalLayer
1616
17from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType17from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
@@ -74,8 +74,8 @@
7474
75 def test_saves_record(self):75 def test_saves_record(self):
76 # A package build can be stored in the database.76 # A package build can be stored in the database.
77 flush_database_updates()
78 store = Store.of(self.package_build)77 store = Store.of(self.package_build)
78 store.flush()
79 retrieved_build = store.find(79 retrieved_build = store.find(
80 PackageBuild,80 PackageBuild,
81 PackageBuild.id == self.package_build.id).one()81 PackageBuild.id == self.package_build.id).one()
@@ -86,6 +86,9 @@
86 self.assertRaises(NotImplementedError, self.package_build.getTitle)86 self.assertRaises(NotImplementedError, self.package_build.getTitle)
87 self.assertRaises(87 self.assertRaises(
88 NotImplementedError, self.package_build.estimateDuration)88 NotImplementedError, self.package_build.estimateDuration)
89 self.assertRaises(
90 NotImplementedError, self.package_build.verifySuccessfulUpload)
91 self.assertRaises(NotImplementedError, self.package_build.notify)
8992
90 def test_default_values(self):93 def test_default_values(self):
91 # PackageBuild has a number of default values.94 # PackageBuild has a number of default values.
@@ -105,15 +108,25 @@
105 self.package_build.build_farm_job.id),108 self.package_build.build_farm_job.id),
106 log_url)109 log_url)
107110
111 def test_storeUploadLog(self):
112 # The given content is uploaded to the librarian and linked as
113 # the upload log.
114 self.package_build.storeUploadLog("Some content")
115 self.failIfEqual(None, self.package_build.upload_log)
116 self.failUnlessEqual(
117 hashlib.sha1("Some content").hexdigest(),
118 self.package_build.upload_log.content.sha1)
119
108 def test_upload_log_url(self):120 def test_upload_log_url(self):
109 # The url of the upload log file is determined by the PackageBuild.121 # The url of the upload log file is determined by the PackageBuild.
110 lfa = self.factory.makeLibraryFileAlias('myuploadlog.txt')122 Store.of(self.package_build).flush()
111 removeSecurityProxy(self.package_build).upload_log = lfa123 build_id = self.package_build.build_farm_job.id
124 self.package_build.storeUploadLog("Some content")
112 log_url = self.package_build.upload_log_url125 log_url = self.package_build.upload_log_url
113 self.failUnlessEqual(126 self.failUnlessEqual(
114 'http://launchpad.dev/~joe/'127 'http://launchpad.dev/~joe/'
115 '+archive/ppa/+build/%d/+files/myuploadlog.txt' % (128 '+archive/ppa/+build/%d/+files/upload_%d_log.txt' % (
116 self.package_build.build_farm_job.id),129 build_id, build_id),
117 log_url)130 log_url)
118131
119132
120133
=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
--- lib/lp/code/model/sourcepackagerecipebuild.py 2010-05-05 15:49:22 +0000
+++ lib/lp/code/model/sourcepackagerecipebuild.py 2010-05-05 15:49:24 +0000
@@ -27,8 +27,8 @@
27from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType27from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
28from lp.buildmaster.model.buildbase import BuildBase28from lp.buildmaster.model.buildbase import BuildBase
29from lp.buildmaster.model.buildqueue import BuildQueue29from lp.buildmaster.model.buildqueue import BuildQueue
30from lp.buildmaster.model.packagebuild import (30from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
31 PackageBuildDerived)31from lp.buildmaster.model.packagebuild import PackageBuild
32from lp.code.interfaces.sourcepackagerecipebuild import (32from lp.code.interfaces.sourcepackagerecipebuild import (
33 ISourcePackageRecipeBuildJob, ISourcePackageRecipeBuildJobSource,33 ISourcePackageRecipeBuildJob, ISourcePackageRecipeBuildJobSource,
34 ISourcePackageRecipeBuild, ISourcePackageRecipeBuildSource)34 ISourcePackageRecipeBuild, ISourcePackageRecipeBuildSource)
@@ -199,7 +199,7 @@
199 return199 return
200200
201201
202class SourcePackageRecipeBuildJob(PackageBuildDerived, Storm):202class SourcePackageRecipeBuildJob(BuildFarmJobDerived, Storm):
203 classProvides(ISourcePackageRecipeBuildJobSource)203 classProvides(ISourcePackageRecipeBuildJobSource)
204 implements(ISourcePackageRecipeBuildJob)204 implements(ISourcePackageRecipeBuildJob)
205205
@@ -222,6 +222,12 @@
222 self.job = job222 self.job = job
223 super(SourcePackageRecipeBuildJob, self).__init__()223 super(SourcePackageRecipeBuildJob, self).__init__()
224224
225 def _set_build_farm_job(self):
226 """Setup the IBuildFarmJob delegate.
227
228 We override this to provide a delegate specific to package builds."""
229 self.build_farm_job = PackageBuild(self.build)
230
225 @classmethod231 @classmethod
226 def new(cls, build, job):232 def new(cls, build, job):
227 """See `ISourcePackageRecipeBuildJobSource`."""233 """See `ISourcePackageRecipeBuildJobSource`."""
228234
=== modified file 'lib/lp/soyuz/model/buildpackagejob.py'
--- lib/lp/soyuz/model/buildpackagejob.py 2010-05-05 15:49:22 +0000
+++ lib/lp/soyuz/model/buildpackagejob.py 2010-05-05 15:49:24 +0000
@@ -18,8 +18,8 @@
18from canonical.database.sqlbase import sqlvalues18from canonical.database.sqlbase import sqlvalues
1919
20from lp.buildmaster.interfaces.buildbase import BuildStatus20from lp.buildmaster.interfaces.buildbase import BuildStatus
21from lp.buildmaster.model.packagebuild import (21from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
22 PackageBuildDerived)22from lp.buildmaster.model.packagebuild import PackageBuild
23from lp.registry.interfaces.sourcepackage import SourcePackageUrgency23from lp.registry.interfaces.sourcepackage import SourcePackageUrgency
24from lp.registry.interfaces.pocket import PackagePublishingPocket24from lp.registry.interfaces.pocket import PackagePublishingPocket
25from lp.soyuz.interfaces.archive import ArchivePurpose25from lp.soyuz.interfaces.archive import ArchivePurpose
@@ -28,7 +28,7 @@
28from lp.soyuz.interfaces.publishing import PackagePublishingStatus28from lp.soyuz.interfaces.publishing import PackagePublishingStatus
2929
3030
31class BuildPackageJob(PackageBuildDerived, Storm):31class BuildPackageJob(BuildFarmJobDerived, Storm):
32 """See `IBuildPackageJob`."""32 """See `IBuildPackageJob`."""
33 implements(IBuildPackageJob)33 implements(IBuildPackageJob)
3434
@@ -42,10 +42,15 @@
42 build = Reference(build_id, 'BinaryPackageBuild.id')42 build = Reference(build_id, 'BinaryPackageBuild.id')
4343
44 def __init__(self, build, job):44 def __init__(self, build, job):
45 """ Setup the IBuildFarmJob delegation when new items are created."""
46 self.build, self.job = build, job45 self.build, self.job = build, job
47 super(BuildPackageJob, self).__init__()46 super(BuildPackageJob, self).__init__()
4847
48 def _set_build_farm_job(self):
49 """Setup the IBuildFarmJob delegate.
50
51 We override this to provide a delegate specific to package builds."""
52 self.build_farm_job = PackageBuild(self.build)
53
49 def score(self):54 def score(self):
50 """See `IBuildPackageJob`."""55 """See `IBuildPackageJob`."""
51 score_pocketname = {56 score_pocketname = {
5257
=== modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py'
--- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-04-28 08:24:54 +0000
+++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-05 15:49:24 +0000
@@ -22,7 +22,8 @@
2222
23from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType23from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
24from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet24from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
25from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived25from lp.buildmaster.model.buildfarmjob import (
26 BuildFarmJob, BuildFarmJobDerived)
26from lp.buildmaster.model.buildqueue import BuildQueue27from lp.buildmaster.model.buildqueue import BuildQueue
27from lp.code.interfaces.branchjob import IRosettaUploadJobSource28from lp.code.interfaces.branchjob import IRosettaUploadJobSource
28from lp.buildmaster.interfaces.buildfarmbranchjob import IBuildFarmBranchJob29from lp.buildmaster.interfaces.buildfarmbranchjob import IBuildFarmBranchJob
@@ -49,6 +50,14 @@
49 def __init__(self, branch_job):50 def __init__(self, branch_job):
50 super(TranslationTemplatesBuildJob, self).__init__(branch_job)51 super(TranslationTemplatesBuildJob, self).__init__(branch_job)
5152
53 def _set_build_farm_job(self):
54 """Setup the IBuildFarmJob delegate.
55
56 We override this to provide a non-database delegate that simply
57 provides required functionality to the queue system."""
58 self.build_farm_job = BuildFarmJob(
59 job_type=BuildFarmJobType.TRANSLATIONTEMPLATESBUILD)
60
52 def score(self):61 def score(self):
53 """See `IBuildFarmJob`."""62 """See `IBuildFarmJob`."""
54 # Hard-code score for now; anything other than 1000 is probably63 # Hard-code score for now; anything other than 1000 is probably

Subscribers

People subscribed via source and target branches

to status/vote changes: