10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
1 |
# Copyright 2010 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
"""Code to build recipes on the buildfarm."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
__all__ = [ |
|
8 |
'RecipeBuildBehavior', |
|
9 |
]
|
|
10 |
||
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
11 |
import traceback |
12 |
||
10739.2.3
by Aaron Bentley
Fix lint errors. |
13 |
from zope.component import adapts |
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
14 |
from zope.interface import implements |
12001.3.18
by j.c.sackett
Updated tests. |
15 |
from zope.security.proxy import removeSecurityProxy |
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
16 |
|
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
17 |
from canonical.config import config |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
18 |
from lp.buildmaster.interfaces.builder import CannotBuild |
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
19 |
from lp.buildmaster.interfaces.buildfarmjobbehavior import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
20 |
IBuildFarmJobBehavior, |
21 |
)
|
|
22 |
from lp.buildmaster.model.buildfarmjobbehavior import BuildFarmJobBehaviorBase |
|
10130.12.22
by Michael Nelson
Updated imports. |
23 |
from lp.code.interfaces.sourcepackagerecipebuild import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
24 |
ISourcePackageRecipeBuildJob, |
25 |
)
|
|
10130.7.28
by Jelmer Vernooij
Provide a hardcoded pocket attribute on SourcePackageRecipeBuild. |
26 |
from lp.registry.interfaces.pocket import PackagePublishingPocket |
10130.7.27
by Jelmer Vernooij
Provide ogrecomponent. |
27 |
from lp.soyuz.adapters.archivedependencies import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
28 |
get_primary_current_component, |
29 |
get_sources_list_for_building, |
|
30 |
)
|
|
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
31 |
|
32 |
||
33 |
class RecipeBuildBehavior(BuildFarmJobBehaviorBase): |
|
34 |
"""How to build a recipe on the build farm."""
|
|
35 |
||
10130.7.19
by Jelmer Vernooij
Merge Michael's recipe build model code. |
36 |
adapts(ISourcePackageRecipeBuildJob) |
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
37 |
implements(IBuildFarmJobBehavior) |
38 |
||
39 |
status = None |
|
40 |
||
10130.7.25
by Jelmer Vernooij
feedback from jml |
41 |
@property
|
10130.7.14
by Jelmer Vernooij
Implement RecipeBuilder.logStartBuild. |
42 |
def build(self): |
43 |
return self.buildfarmjob.build |
|
44 |
||
45 |
@property
|
|
10130.7.25
by Jelmer Vernooij
feedback from jml |
46 |
def display_name(self): |
7675.700.6
by Paul Hummer
Fixed the tests |
47 |
ret = "%s, %s, %s" % ( |
48 |
self.build.distroseries.displayname, self.build.recipe.name, |
|
49 |
self.build.recipe.owner.name) |
|
10130.7.14
by Jelmer Vernooij
Implement RecipeBuilder.logStartBuild. |
50 |
if self._builder is not None: |
51 |
ret += " (on %s)" % self._builder.url |
|
52 |
return ret |
|
53 |
||
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
54 |
def logStartBuild(self, logger): |
10130.7.13
by Jelmer Vernooij
Make RecipeBuilder adapt IBuildSourcePackageFromRecipeJob. |
55 |
"""See `IBuildFarmJobBehavior`."""
|
10130.7.25
by Jelmer Vernooij
feedback from jml |
56 |
logger.info("startBuild(%s)", self.display_name) |
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
57 |
|
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
58 |
def _extraBuildArgs(self, distroarchseries, logger=None): |
10130.7.15
by Jelmer Vernooij
wip. |
59 |
"""
|
60 |
Return the extra arguments required by the slave for the given build.
|
|
61 |
"""
|
|
62 |
# Build extra arguments.
|
|
63 |
args = {} |
|
10130.7.28
by Jelmer Vernooij
Provide a hardcoded pocket attribute on SourcePackageRecipeBuild. |
64 |
suite = self.build.distroseries.name |
65 |
if self.build.pocket != PackagePublishingPocket.RELEASE: |
|
66 |
suite += "-%s" % (self.build.pocket.name.lower()) |
|
67 |
args['suite'] = suite |
|
11121.3.2
by William Grant
Send arch_tag for all existing job types, and fix broken tests. |
68 |
args['arch_tag'] = distroarchseries.architecturetag |
11315.1.1
by Tim Penhey
Handle the case where there is not a preferred email set. |
69 |
requester = self.build.requester |
70 |
if requester.preferredemail is None: |
|
71 |
# Use a constant, known, name and email.
|
|
72 |
args["author_name"] = 'Launchpad Package Builder' |
|
11315.1.2
by Tim Penhey
Use the configured noreply email address. |
73 |
args["author_email"] = config.canonical.noreply_from_address |
11315.1.1
by Tim Penhey
Handle the case where there is not a preferred email set. |
74 |
else: |
75 |
args["author_name"] = requester.displayname |
|
12001.3.18
by j.c.sackett
Updated tests. |
76 |
# We have to remove the security proxy here b/c there's not a
|
77 |
# logged in entity, and anonymous email lookups aren't allowed.
|
|
78 |
# Don't keep the naked requester around though.
|
|
79 |
args["author_email"] = removeSecurityProxy( |
|
80 |
requester).preferredemail.email |
|
10130.7.18
by Jelmer Vernooij
Further work on dispatchBuildToSlave. |
81 |
args["recipe_text"] = str(self.build.recipe.builder_recipe) |
10130.7.21
by Jelmer Vernooij
Fix recipe builder tests. |
82 |
args['archive_purpose'] = self.build.archive.purpose.name |
10130.7.27
by Jelmer Vernooij
Provide ogrecomponent. |
83 |
args["ogrecomponent"] = get_primary_current_component( |
10130.7.34
by Jelmer Vernooij
review feedback from jono. |
84 |
self.build.archive, self.build.distroseries, |
7675.700.6
by Paul Hummer
Fixed the tests |
85 |
None) |
7675.502.26
by Jonathan Lange
Merge db-stable |
86 |
args['archives'] = get_sources_list_for_building(self.build, |
7675.700.6
by Paul Hummer
Fixed the tests |
87 |
distroarchseries, None) |
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
88 |
|
89 |
# config.builddmaster.bzr_builder_sources_list can contain a
|
|
90 |
# sources.list entry for an archive that will contain a
|
|
91 |
# bzr-builder package that needs to be used to build this
|
|
92 |
# recipe.
|
|
10795.2.4
by Julian Edwards
Fixes suggested by noodles' review |
93 |
try: |
94 |
extra_archive = config.builddmaster.bzr_builder_sources_list |
|
95 |
except AttributeError: |
|
96 |
extra_archive = None |
|
97 |
||
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
98 |
if extra_archive is not None: |
99 |
try: |
|
100 |
sources_line = extra_archive % ( |
|
101 |
{'series': self.build.distroseries.name}) |
|
102 |
args['archives'].append(sources_line) |
|
10795.2.4
by Julian Edwards
Fixes suggested by noodles' review |
103 |
except StandardError: |
10795.2.2
by Julian Edwards
Ensure that recipe builds send a configured sources.list to the slave for an archive that contains the bzr-builder package |
104 |
# Someone messed up the config, don't add it.
|
7675.700.6
by Paul Hummer
Fixed the tests |
105 |
if logger: |
106 |
logger.error( |
|
107 |
"Exception processing bzr_builder_sources_list:\n%s" |
|
108 |
% traceback.format_exc()) |
|
10795.2.4
by Julian Edwards
Fixes suggested by noodles' review |
109 |
|
10739.2.4
by Aaron Bentley
Updates from review. |
110 |
args['distroseries_name'] = self.build.distroseries.name |
10130.7.15
by Jelmer Vernooij
wip. |
111 |
return args |
112 |
||
10130.7.2
by Jonathan Lange
Initial recipe builder behaviour stuff. |
113 |
def dispatchBuildToSlave(self, build_queue_id, logger): |
10130.7.13
by Jelmer Vernooij
Make RecipeBuilder adapt IBuildSourcePackageFromRecipeJob. |
114 |
"""See `IBuildFarmJobBehavior`."""
|
10130.7.15
by Jelmer Vernooij
wip. |
115 |
|
10130.7.26
by Jelmer Vernooij
Move functionality for finding a distroarchseries by processor onto |
116 |
distroseries = self.build.distroseries |
10130.7.15
by Jelmer Vernooij
wip. |
117 |
# Start the binary package build on the slave builder. First
|
118 |
# we send the chroot.
|
|
10130.7.26
by Jelmer Vernooij
Move functionality for finding a distroarchseries by processor onto |
119 |
distroarchseries = distroseries.getDistroArchSeriesByProcessor( |
120 |
self._builder.processor) |
|
121 |
if distroarchseries is None: |
|
10130.7.23
by Jelmer Vernooij
Remove i386-hardcoded bits. |
122 |
raise CannotBuild("Unable to find distroarchseries for %s in %s" % |
123 |
(self._builder.processor.name, |
|
124 |
self.build.distroseries.displayname)) |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
125 |
args = self._extraBuildArgs(distroarchseries, logger) |
10130.7.21
by Jelmer Vernooij
Fix recipe builder tests. |
126 |
chroot = distroarchseries.getChroot() |
127 |
if chroot is None: |
|
7675.502.26
by Jonathan Lange
Merge db-stable |
128 |
raise CannotBuild("Unable to find a chroot for %s" % |
10130.7.21
by Jelmer Vernooij
Fix recipe builder tests. |
129 |
distroarchseries.displayname) |
11929.3.1
by Julian Edwards
Add extra default logging to help discover problems in the Deferred chain when dispatching. |
130 |
logger.info( |
131 |
"Sending chroot file for recipe build to %s" % self._builder.name) |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
132 |
d = self._builder.slave.cacheFile(logger, chroot) |
133 |
||
134 |
def got_cache_file(ignored): |
|
135 |
# Generate a string which can be used to cross-check when obtaining
|
|
136 |
# results so we know we are referring to the right database object in
|
|
137 |
# subsequent runs.
|
|
138 |
buildid = "%s-%s" % (self.build.id, build_queue_id) |
|
139 |
cookie = self.buildfarmjob.generateSlaveBuildCookie() |
|
140 |
chroot_sha1 = chroot.content.sha1 |
|
11929.3.1
by Julian Edwards
Add extra default logging to help discover problems in the Deferred chain when dispatching. |
141 |
logger.info( |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
142 |
"Initiating build %s on %s" % (buildid, self._builder.url)) |
143 |
||
144 |
return self._builder.slave.build( |
|
145 |
cookie, "sourcepackagerecipe", chroot_sha1, {}, args) |
|
146 |
||
147 |
def log_build_result((status, info)): |
|
148 |
message = """%s (%s): |
|
149 |
***** RESULT *****
|
|
150 |
%s |
|
151 |
%s: %s |
|
152 |
******************
|
|
153 |
""" % ( |
|
154 |
self._builder.name, |
|
155 |
self._builder.url, |
|
156 |
args, |
|
157 |
status, |
|
158 |
info, |
|
159 |
)
|
|
160 |
logger.info(message) |
|
161 |
||
162 |
return d.addCallback(got_cache_file).addCallback(log_build_result) |
|
10130.7.15
by Jelmer Vernooij
wip. |
163 |
|
164 |
def verifyBuildRequest(self, logger): |
|
165 |
"""Assert some pre-build checks.
|
|
166 |
||
167 |
The build request is checked:
|
|
168 |
* Virtualized builds can't build on a non-virtual builder
|
|
169 |
* Ensure that we have a chroot
|
|
170 |
* Ensure that the build pocket allows builds for the current
|
|
171 |
distroseries state.
|
|
172 |
"""
|
|
173 |
build = self.build |
|
10604.4.2
by William Grant
Revert mistaken change. |
174 |
assert not (not self._builder.virtualized and build.is_virtualized), ( |
10855.1.1
by Aaron Bentley
Fix verifyBuildRequest to use valid attribute |
175 |
"Attempt to build virtual item on a non-virtual builder.") |
10130.7.15
by Jelmer Vernooij
wip. |
176 |
|
7675.467.4
by Jonathan Lange
Merge jelmer's branch, resolving conflicts. |
177 |
# This should already have been checked earlier, but just check again
|
10130.7.32
by Jelmer Vernooij
Factor out checks for allowing uploads to a pocket. |
178 |
# here in case of programmer errors.
|
10156.2.8
by Jelmer Vernooij
Remove more references to lp.archiveuploader.permission. |
179 |
reason = build.archive.checkUploadToPocket( |
180 |
build.distroseries, build.pocket) |
|
10130.7.35
by Jelmer Vernooij
More review feedback from jono. |
181 |
assert reason is None, ( |
182 |
"%s (%s) can not be built for pocket %s: invalid pocket due " |
|
7675.502.26
by Jonathan Lange
Merge db-stable |
183 |
"to the series status of %s." % |
10130.7.35
by Jelmer Vernooij
More review feedback from jono. |
184 |
(build.title, build.id, build.pocket.name, |
185 |
build.distroseries.name)) |
|
10130.8.2
by Michael Nelson
Moved _handleStatus_OK from IBuild to BuildBase as it's common between SPRecipe builds and binary builds. Also added slaveStatus() to the RecipeBuildBehavior. |
186 |
|
10604.4.4
by William Grant
IBFJB.slaveStatus -> updateSlaveStatus; no longer returns the updated dict. |
187 |
def updateSlaveStatus(self, raw_slave_status, status): |
10604.4.1
by William Grant
Move the common IBFJB.slaveStatus components into Builder.slaveStatus. |
188 |
"""Parse the recipe build specific status info into the status dict.
|
10130.8.2
by Michael Nelson
Moved _handleStatus_OK from IBuild to BuildBase as it's common between SPRecipe builds and binary builds. Also added slaveStatus() to the RecipeBuildBehavior. |
189 |
|
190 |
This includes:
|
|
191 |
* filemap => dictionary or None
|
|
192 |
* dependencies => string or None
|
|
193 |
"""
|
|
10604.4.1
by William Grant
Move the common IBFJB.slaveStatus components into Builder.slaveStatus. |
194 |
build_status_with_files = ( |
195 |
'BuildStatus.OK', |
|
196 |
'BuildStatus.PACKAGEFAIL', |
|
197 |
'BuildStatus.DEPFAIL', |
|
198 |
)
|
|
199 |
if (status['builder_status'] == 'BuilderStatus.WAITING' and |
|
200 |
status['build_status'] in build_status_with_files): |
|
201 |
status['filemap'] = raw_slave_status[3] |
|
202 |
status['dependencies'] = raw_slave_status[4] |