~launchpad-pqm/launchpad/devel

13668.1.21 by Curtis Hovey
Updated copyrights.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4983.1.2 by Curtis Hovey
Added pylint exceptions to database classes.
4
# pylint: disable-msg=E0611,W0212
1670 by Canonical.com Patch Queue Manager
Big lot of database clean-up r=stub except for resolution of conflicts.
5
6
__metaclass__ = type
12156.9.15 by Steve Kowalik
Finish killing binarypackagebuild.txt.
7
__all__ = [
8
    'BinaryPackageBuild',
9
    'BinaryPackageBuildSet',
10
    ]
1670 by Canonical.com Patch Queue Manager
Big lot of database clean-up r=stub except for resolution of conflicts.
11
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
12
import datetime
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
13
import logging
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
14
import operator
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
15
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
16
import apt_pkg
17
from sqlobject import SQLObjectNotFound
18
from storm.expr import (
19
    Desc,
20
    Join,
21
    LeftJoin,
12588.1.1 by Robert Collins
Eager load PackageBuild and BuildFarmJob for Person:+uploaded-packages.
22
    SQL,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
23
    )
24
from storm.locals import (
25
    Int,
26
    Reference,
27
    )
28
from storm.store import (
29
    EmptyResultSet,
30
    Store,
31
    )
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
32
from storm.zope import IResultSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
33
from zope.component import getUtility
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
34
from zope.interface import implements
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
35
11626.3.2 by Curtis Hovey
Move tales gto lp.app.
36
from lp.app.browser.tales import DurationFormatterAPI
11270.1.3 by Tim Penhey
Changed NotFoundError imports - gee there were a lot of them.
37
from lp.app.errors import NotFoundError
13130.1.12 by Curtis Hovey
Sorted imports.
38
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
39
from lp.archivepublisher.utils import get_ppa_reference
11458.1.2 by Jelmer Vernooij
Move BuildFarmJobType to lp.buildmaster.enums.
40
from lp.buildmaster.enums import (
11458.1.4 by Jelmer Vernooij
Proper sorting in imports.
41
    BuildFarmJobType,
11458.1.2 by Jelmer Vernooij
Move BuildFarmJobType to lp.buildmaster.enums.
42
    BuildStatus,
43
    )
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
44
from lp.buildmaster.interfaces.packagebuild import IPackageBuildSource
45
from lp.buildmaster.model.builder import Builder
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
46
from lp.buildmaster.model.buildfarmjob import BuildFarmJob
7675.509.139 by William Grant
Move (I)BuildQueue(Set) to lp.buildmaster.
47
from lp.buildmaster.model.buildqueue import BuildQueue
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
48
from lp.buildmaster.model.packagebuild import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
49
    PackageBuild,
50
    PackageBuildDerived,
51
    )
14606.3.1 by William Grant
Merge canonical.database into lp.services.database.
52
from lp.services.config import config
14265.5.1 by Raphael Badin
Eager load stuff.
53
from lp.services.database.bulk import load_related
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
54
from lp.services.database.decoratedresultset import DecoratedResultSet
14578.2.1 by William Grant
Move librarian stuff from canonical.launchpad to lp.services.librarian. canonical.librarian remains untouched.
55
from lp.services.database.lpstorm import (
56
    IMasterObject,
57
    ISlaveStore,
58
    IStore,
59
    )
14606.3.1 by William Grant
Merge canonical.database into lp.services.database.
60
from lp.services.database.sqlbase import (
61
    quote_like,
62
    SQLBase,
63
    sqlvalues,
64
    )
7675.391.14 by Muharem Hrnjadovic
Fixing code to make tests pass.
65
from lp.services.job.model.job import Job
14578.2.1 by William Grant
Move librarian stuff from canonical.launchpad to lp.services.librarian. canonical.librarian remains untouched.
66
from lp.services.librarian.browser import ProxiedLibraryFileAlias
67
from lp.services.librarian.model import (
68
    LibraryFileAlias,
69
    LibraryFileContent,
70
    )
14606.3.1 by William Grant
Merge canonical.database into lp.services.database.
71
from lp.services.mail.helpers import (
72
    get_contact_email_addresses,
73
    get_email_template,
74
    )
13668.1.22 by Curtis Hovey
Sorted imports.
75
from lp.services.mail.sendmail import (
76
    format_address,
77
    simple_sendmail,
78
    )
14606.3.1 by William Grant
Merge canonical.database into lp.services.database.
79
from lp.services.webapp import canonical_url
80
from lp.services.webapp.interfaces import (
81
    DEFAULT_FLAVOR,
82
    IStoreSelector,
83
    MAIN_STORE,
84
    )
11411.6.2 by Julian Edwards
Change code imports for ArchivePurpose and ArchiveStatus
85
from lp.soyuz.enums import ArchivePurpose
10667.2.2 by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet
86
from lp.soyuz.interfaces.binarypackagebuild import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
87
    BuildSetStatus,
88
    CannotBeRescored,
89
    IBinaryPackageBuild,
90
    IBinaryPackageBuildSet,
12259.1.1 by Julian Edwards
Make buildd-retry-depwait skip over binaries with bad dependencies instead of crashing.
91
    UnparsableDependencies,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
92
    )
9113.7.7 by Jonathan Lange
Update all the rest of the imports of PackagePublishingPocket.
93
from lp.soyuz.interfaces.publishing import active_publishing_status
12233.2.1 by Julian Edwards
first stab, failing
94
from lp.soyuz.model.binarypackagename import BinaryPackageName
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
95
from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
7675.391.11 by Muharem Hrnjadovic
Build fixes.
96
from lp.soyuz.model.buildpackagejob import BuildPackageJob
8636.3.3 by Julian Edwards
Push proxied lfas instead of plain librarian links.
97
from lp.soyuz.model.files import BinaryPackageFile
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
98
from lp.soyuz.model.publishing import SourcePackagePublishingHistory
99
from lp.soyuz.model.queue import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
100
    PackageUpload,
101
    PackageUploadBuild,
102
    )
3691.373.5 by Christian Reis
Move DBSchema and Item into webapp.enum, and put EnumCol into canonical.database.enumcol
103
6642.1.1 by Celso Providelo
Fixing bug #237950 (Storing upload_log content for FAILEDTOUPLOAD build in librarian).
104
7675.687.48 by Michael Nelson
Initial update of binarypackagebuild to use new table, replaced calculated_buildstart with build_started.
105
class BinaryPackageBuild(PackageBuildDerived, SQLBase):
106
    implements(IBinaryPackageBuild)
107
    _table = 'BinaryPackageBuild'
3691.93.25 by Christian Reis
Fix architecture handling in the queue builder. Make architecturehintlist NOT NULL and fix sampledata for it. Clean up the portions of the buildmaster script related to build creation. Severely enhance and clarify the buildd-queuebuilder test. As an added bonus clean up the filechunks() methods and instead use librarian.utils.
108
    _defaultOrder = 'id'
1035 by Canonical.com Patch Queue Manager
Some more soyuz reestructuration from kiko
109
10130.8.8 by William Grant
Provide (I)BuildBase.createBuildQueueEntry (moved from IBuild), and make it work on both implementations.
110
    build_farm_job_type = BuildFarmJobType.PACKAGEBUILD
111
7675.687.48 by Michael Nelson
Initial update of binarypackagebuild to use new table, replaced calculated_buildstart with build_started.
112
    package_build_id = Int(name='package_build', allow_none=False)
113
    package_build = Reference(package_build_id, 'PackageBuild.id')
114
7675.687.70 by Michael Nelson
More changes to get test_publishing passing.
115
    distro_arch_series_id = Int(name='distro_arch_series', allow_none=False)
116
    distro_arch_series = Reference(
117
        distro_arch_series_id, 'DistroArchSeries.id')
118
    source_package_release_id = Int(
119
        name='source_package_release', allow_none=False)
120
    source_package_release = Reference(
121
        source_package_release_id, 'SourcePackageRelease.id')
7675.391.11 by Muharem Hrnjadovic
Build fixes.
122
7675.687.51 by Michael Nelson
Put buildqueue_record back on BinaryPackageBuild.
123
    @property
124
    def buildqueue_record(self):
125
        """See `IBuild`."""
126
        store = Store.of(self)
127
        results = store.find(
128
            BuildQueue,
129
            BuildPackageJob.job == BuildQueue.jobID,
130
            BuildPackageJob.build == self.id)
131
        return results.one()
132
8523.1.1 by Celso Providelo
Fixing bug #378828 (fixing failure when updating dependencies of build for deleted source publications). Avoiding the need of falling-back to the source package release original component in production.
133
    def _getLatestPublication(self):
8137.12.1 by Celso Providelo
Fixing #354361 (Exposing IBuild.current_source_publication API).
134
        store = Store.of(self)
135
        results = store.find(
136
            SourcePackagePublishingHistory,
137
            SourcePackagePublishingHistory.archive == self.archive,
7675.687.49 by Michael Nelson
Ensured that interface is provided.
138
            SourcePackagePublishingHistory.distroseries == self.distro_series,
8137.12.1 by Celso Providelo
Fixing #354361 (Exposing IBuild.current_source_publication API).
139
            SourcePackagePublishingHistory.sourcepackagerelease ==
7675.687.49 by Michael Nelson
Ensured that interface is provided.
140
                self.source_package_release)
8523.1.1 by Celso Providelo
Fixing bug #378828 (fixing failure when updating dependencies of build for deleted source publications). Avoiding the need of falling-back to the source package release original component in production.
141
        return results.order_by(
8137.12.1 by Celso Providelo
Fixing #354361 (Exposing IBuild.current_source_publication API).
142
            Desc(SourcePackagePublishingHistory.id)).first()
143
8523.1.1 by Celso Providelo
Fixing bug #378828 (fixing failure when updating dependencies of build for deleted source publications). Avoiding the need of falling-back to the source package release original component in production.
144
    @property
145
    def current_component(self):
146
        """See `IBuild`."""
147
        latest_publication = self._getLatestPublication()
13045.23.1 by William Grant
BinaryPackageBuild.current_component returns None if there are no source publications, as happens with some buggy gina-created builds on production.
148
        # Production has some buggy builds without source publications.
149
        # They seem to have been created by early versions of gina and
150
        # the readding of hppa.
151
        if latest_publication is not None:
152
            return latest_publication.component
8523.1.1 by Celso Providelo
Fixing bug #378828 (fixing failure when updating dependencies of build for deleted source publications). Avoiding the need of falling-back to the source package release original component in production.
153
154
    @property
155
    def current_source_publication(self):
156
        """See `IBuild`."""
157
        latest_publication = self._getLatestPublication()
158
        if (latest_publication is not None and
159
            latest_publication.status in active_publishing_status):
160
            return latest_publication
161
        return None
4981.4.1 by Julian Edwards
The build details page now includes the current component for the source
162
163
    @property
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
164
    def upload_changesfile(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
165
        """See `IBuild`"""
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
166
        package_upload = self.package_upload
167
        if package_upload is None:
3147.1.1 by Celso Providelo
Removing unused/bogus changes and gpgsigningkey from Build table, adding a new 'changesfile' property to IBuild which retrieves the respective IDistroReleaseQueue.changesfile object for this build and finally improve build.txt test.
168
            return None
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
169
        return package_upload.changesfile
170
171
    @property
11567.1.1 by Julian Edwards
Add changesfile_url to IBinaryPackageBuild and export it on the API
172
    def changesfile_url(self):
173
        """See `IBinaryPackageBuild`."""
174
        changesfile = self.upload_changesfile
175
        if changesfile is None:
176
            return None
177
        return ProxiedLibraryFileAlias(changesfile, self).http_url
178
179
    @property
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
180
    def package_upload(self):
181
        """See `IBuild`."""
182
        store = Store.of(self)
8688.1.4 by Celso Providelo
new comment versions on PU.changesfile JOIN, it's complex.
183
        # The join on 'changesfile' is not only used only for
184
        # pre-fetching the corresponding library file, so callsites
185
        # don't have to issue an extra query. It is also important
186
        # for excluding delayed-copies, because they might match
187
        # the publication context but will not contain as changesfile.
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
188
        origin = [
189
            PackageUploadBuild,
190
            Join(PackageUpload,
191
                 PackageUploadBuild.packageuploadID == PackageUpload.id),
192
            Join(LibraryFileAlias,
193
                 LibraryFileAlias.id == PackageUpload.changesfileID),
194
            Join(LibraryFileContent,
195
                 LibraryFileContent.id == LibraryFileAlias.contentID),
196
            ]
197
        results = store.using(*origin).find(
198
            (PackageUpload, LibraryFileAlias, LibraryFileContent),
199
            PackageUploadBuild.build == self,
200
            PackageUpload.archive == self.archive,
7675.687.49 by Michael Nelson
Ensured that interface is provided.
201
            PackageUpload.distroseries == self.distro_series)
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
202
8537.6.5 by Celso Providelo
applying review comments, r=allenap.
203
        # Return the unique `PackageUpload` record that corresponds to the
204
        # upload of the result of this `Build`, load the `LibraryFileAlias`
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
205
        # and the `LibraryFileContent` in cache because it's most likely
206
        # they will be needed.
8537.6.3 by Celso Providelo
Locking PackageUpload lookups to expect a single result and add a doctests checking it against the current sampledata.
207
        return DecoratedResultSet(results, operator.itemgetter(0)).one()
3147.1.1 by Celso Providelo
Removing unused/bogus changes and gpgsigningkey from Build table, adding a new 'changesfile' property to IBuild which retrieves the respective IDistroReleaseQueue.changesfile object for this build and finally improve build.txt test.
208
209
    @property
7675.687.49 by Michael Nelson
Ensured that interface is provided.
210
    def distro_series(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
211
        """See `IBuild`"""
7675.687.49 by Michael Nelson
Ensured that interface is provided.
212
        return self.distro_arch_series.distroseries
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
213
214
    @property
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
215
    def distribution(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
216
        """See `IBuild`"""
7675.687.49 by Michael Nelson
Ensured that interface is provided.
217
        return self.distro_series.distribution
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
218
219
    @property
5814.5.4 by Julian Edwards
Apply DBA changes to the db patch and convert to Americanised spelling.
220
    def is_virtualized(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
221
        """See `IBuild`"""
5814.5.4 by Julian Edwards
Apply DBA changes to the db patch and convert to Americanised spelling.
222
        return self.archive.require_virtualized
3691.447.5 by Celso Providelo
BuilderGroup.firstAvailable to support trusted/untrested builder lookup, IBuildQueueSet.calculateCandidates to return all candidates across archive, dispatching job is aware of trust/untrusted jobs, IBuiild/IBuildQueue have a 'is_trusted' property and finally test fixing.
223
224
    @property
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
225
    def title(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
226
        """See `IBuild`"""
3147.5.33 by Celso Providelo
fix build timestamps presentation as suggested in bug #49757 and create an specific adapter for icon presentation for IBuild instances.
227
        return '%s build of %s %s in %s %s %s' % (
7675.687.49 by Michael Nelson
Ensured that interface is provided.
228
            self.distro_arch_series.architecturetag,
229
            self.source_package_release.name,
230
            self.source_package_release.version,
231
            self.distribution.name, self.distro_series.name, self.pocket.name)
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
232
233
    @property
3023.2.22 by Celso Providelo
Fix build records presentation, auxiliary IBuild.was_built property to wrokaround records with empty datebuilt, inserted by gina.
234
    def was_built(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
235
        """See `IBuild`"""
7675.687.49 by Michael Nelson
Ensured that interface is provided.
236
        return self.status not in [BuildStatus.NEEDSBUILD,
7675.695.4 by Michael Nelson
Added IPackageBuild.distroseries.
237
                                   BuildStatus.BUILDING,
11039.2.47 by Jelmer Vernooij
Display uploading builds in counts.
238
                                   BuildStatus.UPLOADING,
7675.695.4 by Michael Nelson
Added IPackageBuild.distroseries.
239
                                   BuildStatus.SUPERSEDED]
3023.2.22 by Celso Providelo
Fix build records presentation, auxiliary IBuild.was_built property to wrokaround records with empty datebuilt, inserted by gina.
240
241
    @property
7507.2.1 by Michael Nelson
Exposing of IBuild and a method on IArchive for dynamic page updates.
242
    def arch_tag(self):
243
        """See `IBuild`."""
7675.687.49 by Michael Nelson
Ensured that interface is provided.
244
        return self.distro_arch_series.architecturetag
7507.2.1 by Michael Nelson
Exposing of IBuild and a method on IArchive for dynamic page updates.
245
246
    @property
7675.687.84 by Michael Nelson
Updated so that PackageBuild urls are always in the context of the archive,
247
    def log_url(self):
7675.687.87 by Michael Nelson
Started build.txt.
248
        """See `IPackageBuild`.
7675.687.84 by Michael Nelson
Updated so that PackageBuild urls are always in the context of the archive,
249
250
        Overridden here for the case of builds for distro archives,
251
        currently only supported for binary package builds.
252
        """
253
        if self.log is None:
254
            return None
255
        return ProxiedLibraryFileAlias(self.log, self).http_url
256
257
    @property
7675.687.87 by Michael Nelson
Started build.txt.
258
    def upload_log_url(self):
259
        """See `IPackageBuild`.
260
261
        Overridden here for the case of builds for distro archives,
262
        currently only supported for binary package builds.
263
        """
264
        if self.upload_log is None:
265
            return None
266
        return ProxiedLibraryFileAlias(self.upload_log, self).http_url
267
268
    @property
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
269
    def distributionsourcepackagerelease(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
270
        """See `IBuild`."""
8294.6.1 by Julian Edwards
First stab at code-reorg. Still got a discrepancy on stuff I assigned to registry but not migrated yet.
271
        from lp.soyuz.model.distributionsourcepackagerelease \
3032.1.3 by Celso Providelo
Last minute soyuz changes, fix build presentation and security.cfg
272
             import (
273
            DistributionSourcePackageRelease)
274
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
275
        return DistributionSourcePackageRelease(
7675.687.49 by Michael Nelson
Ensured that interface is provided.
276
            distribution=self.distribution,
277
            sourcepackagerelease=self.source_package_release)
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
278
12233.2.2 by Jeroen Vermeulen
Prefetch BinaryPackageNames and BinaryPackageFiles etc.
279
    def getBinaryPackageNamesForDisplay(self):
280
        """See `IBuildView`."""
12233.2.1 by Julian Edwards
first stab, failing
281
        store = Store.of(self)
282
        result = store.find(
283
            (BinaryPackageRelease, BinaryPackageName),
284
            BinaryPackageRelease.build == self,
285
            BinaryPackageRelease.binarypackagename == BinaryPackageName.id,
12233.2.2 by Jeroen Vermeulen
Prefetch BinaryPackageNames and BinaryPackageFiles etc.
286
            BinaryPackageName.id == BinaryPackageRelease.binarypackagenameID)
287
        return result.order_by(
288
            [BinaryPackageName.name, BinaryPackageRelease.id])
12233.2.1 by Julian Edwards
first stab, failing
289
290
    def getBinaryFilesForDisplay(self):
12233.2.2 by Jeroen Vermeulen
Prefetch BinaryPackageNames and BinaryPackageFiles etc.
291
        """See `IBuildView`."""
12233.2.1 by Julian Edwards
first stab, failing
292
        store = Store.of(self)
293
        result = store.find(
294
            (BinaryPackageRelease, BinaryPackageFile, LibraryFileAlias,
295
             LibraryFileContent),
296
            BinaryPackageRelease.build == self,
297
            BinaryPackageRelease.id ==
298
                BinaryPackageFile.binarypackagereleaseID,
299
            LibraryFileAlias.id == BinaryPackageFile.libraryfileID,
300
            LibraryFileContent.id == LibraryFileAlias.contentID)
12233.2.2 by Jeroen Vermeulen
Prefetch BinaryPackageNames and BinaryPackageFiles etc.
301
        return result.order_by(
302
            [LibraryFileAlias.filename, BinaryPackageRelease.id]).config(
303
            distinct=True)
12233.2.1 by Julian Edwards
first stab, failing
304
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
305
    @property
306
    def binarypackages(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
307
        """See `IBuild`."""
6422.3.1 by Julian Edwards
Add a PackageUpload decorator to cache some values for the queue template.
308
        return BinaryPackageRelease.select("""
309
            BinaryPackageRelease.build = %s AND
310
            BinaryPackageRelease.binarypackagename = BinaryPackageName.id
311
            """ % sqlvalues(self),
312
            clauseTables=["BinaryPackageName"],
313
            orderBy=["BinaryPackageName.name", "BinaryPackageRelease.id"],
314
            prejoins=["binarypackagename", "component", "section"])
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
315
2850.2.3 by Celso Providelo
Reset Build functionality and tests.
316
    @property
4271.4.6 by Julian Edwards
Merge RF and fix distrorelease -> distroseries incompatibilities.
317
    def distroarchseriesbinarypackages(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
318
        """See `IBuild`."""
4271.4.2 by Julian Edwards
Change links to resulting binaries on the build page so that they point at
319
        # Avoid circular import by importing locally.
11869.8.3 by Jonathan Lange
Fix failing imports from most of the tests. Also clean up flakes.
320
        from lp.soyuz.model.distroarchseriesbinarypackagerelease import (
5152.5.8 by Celso Providelo
applying review comments, r=bac.
321
            DistroArchSeriesBinaryPackageRelease)
4271.4.6 by Julian Edwards
Merge RF and fix distrorelease -> distroseries incompatibilities.
322
        return [DistroArchSeriesBinaryPackageRelease(
7675.687.49 by Michael Nelson
Ensured that interface is provided.
323
            self.distro_arch_series, bp)
4271.4.2 by Julian Edwards
Change links to resulting binaries on the build page so that they point at
324
            for bp in self.binarypackages]
325
326
    @property
3147.5.28 by Celso Providelo
rename IBuild.reset() due collision with SQLBase.reset() method, the problem manifest itself when we invoke ztm.abort() in scripts using IBuild
327
    def can_be_retried(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
328
        """See `IBuild`."""
4922.2.10 by Julian Edwards
Apply Barry's review comments.
329
        # First check that the slave scanner would pick up the build record
5814.5.1 by Julian Edwards
Alter IBuilder.trusted to IBuilder.virtualised and fix bug 139594 into the
330
        # if we reset it.  PPA and Partner builds are always ok.
331
        if (self.archive.purpose == ArchivePurpose.PRIMARY and
7675.687.49 by Michael Nelson
Ensured that interface is provided.
332
            not self.distro_series.canUploadToPocket(self.pocket)):
4922.2.10 by Julian Edwards
Apply Barry's review comments.
333
            # The slave scanner would not pick this up, so it cannot be
334
            # re-tried.
3500.2.28 by Celso Providelo
More review comments from kiko
335
            return False
3500.2.12 by Celso Providelo
Improve initialiase-from-parent to set changeslist if required, added a script top-level tast for it. Fix IBuild.can_be_reset to not reset released builds.
336
7675.687.49 by Michael Nelson
Ensured that interface is provided.
337
        failed_statuses = [
6620.1.1 by Muharem Hrnjadovic
rolled the code back
338
            BuildStatus.FAILEDTOBUILD,
339
            BuildStatus.MANUALDEPWAIT,
340
            BuildStatus.CHROOTWAIT,
341
            BuildStatus.FAILEDTOUPLOAD,
342
            ]
343
4922.2.10 by Julian Edwards
Apply Barry's review comments.
344
        # If the build is currently in any of the failed states,
345
        # it may be retried.
7675.687.49 by Michael Nelson
Ensured that interface is provided.
346
        return self.status in failed_statuses
2850.2.3 by Celso Providelo
Reset Build functionality and tests.
347
3500.2.4 by Celso Providelo
Fix bug #44240 (build rescore input validation), bug #44227 (build rescore corner case), bug #44208 (build rescore messages layout) and bug #43802 (reduce builds list batch size to expensive queries, needs more investigation)
348
    @property
349
    def can_be_rescored(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
350
        """See `IBuild`."""
7675.687.49 by Michael Nelson
Ensured that interface is provided.
351
        return self.status is BuildStatus.NEEDSBUILD
3147.5.33 by Celso Providelo
fix build timestamps presentation as suggested in bug #49757 and create an specific adapter for icon presentation for IBuild instances.
352
14213.2.4 by Julian Edwards
Add code to implement can_be_cancelled
353
    @property
354
    def can_be_cancelled(self):
355
        """See `IBuild`."""
356
        if not self.buildqueue_record:
357
            return False
358
        if self.buildqueue_record.virtualized is False:
359
            return False
360
361
        cancellable_statuses = [
362
            BuildStatus.BUILDING,
363
            BuildStatus.NEEDSBUILD,
364
            ]
365
        return self.status in cancellable_statuses
366
3147.5.28 by Celso Providelo
rename IBuild.reset() due collision with SQLBase.reset() method, the problem manifest itself when we invoke ztm.abort() in scripts using IBuild
367
    def retry(self):
4285.3.65 by Celso Providelo
review comments [r=barry].
368
        """See `IBuild`."""
5152.5.8 by Celso Providelo
applying review comments, r=bac.
369
        assert self.can_be_retried, "Build %s cannot be retried" % self.id
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
370
        self.status = BuildStatus.NEEDSBUILD
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
371
        self.date_finished = None
372
        self.date_started = None
2850.2.3 by Celso Providelo
Reset Build functionality and tests.
373
        self.builder = None
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
374
        self.log = None
6642.1.1 by Celso Providelo
Fixing bug #237950 (Storing upload_log content for FAILEDTOUPLOAD build in librarian).
375
        self.upload_log = None
3147.2.29 by Celso Providelo
Storing and update missing dependencies in DEPWAIT build records (only master side code)
376
        self.dependencies = None
10130.11.12 by William Grant
Rename createBuildQueueEntry to queueBuild.
377
        self.queueBuild()
2850.2.3 by Celso Providelo
Reset Build functionality and tests.
378
8520.5.4 by Julian Edwards
Add IBuild.rescore() and make the view code use it.
379
    def rescore(self, score):
380
        """See `IBuild`."""
381
        if not self.can_be_rescored:
382
            raise CannotBeRescored("Build cannot be rescored.")
383
384
        self.buildqueue_record.manualScore(score)
385
12221.7.1 by rvb
add score to the api of a build record + test
386
    @property
12221.7.2 by rvb
rename _api_score to api_score
387
    def api_score(self):
12221.7.1 by rvb
add score to the api of a build record + test
388
        """See `IBinaryPackageBuild`."""
389
        # Score of the related buildqueue record (if any)
390
        if self.buildqueue_record is None:
391
            return None
392
        else:
393
            return self.buildqueue_record.lastscore
394
14213.2.6 by Julian Edwards
Add cancel() method on BinaryPackageBuild.
395
    def cancel(self):
396
        """See `IBinaryPackageBuild`."""
397
        if not self.can_be_cancelled:
398
            return
399
400
        # If the build is currently building we need to tell the
401
        # buildd-manager to terminate it.
402
        if self.status == BuildStatus.BUILDING:
403
            self.status = BuildStatus.CANCELLING
404
            return
405
406
        # Otherwise we can cancel it here.
407
        self.buildqueue_record.cancel()
408
10130.8.8 by William Grant
Provide (I)BuildBase.createBuildQueueEntry (moved from IBuild), and make it work on both implementations.
409
    def makeJob(self):
11411.7.24 by j.c.sackett
Merged from devel.
410
        """See `IBuildFarmJob`."""
10130.8.8 by William Grant
Provide (I)BuildBase.createBuildQueueEntry (moved from IBuild), and make it work on both implementations.
411
        store = Store.of(self)
412
        job = Job()
413
        store.add(job)
10667.4.3 by Michael Nelson
Tweaks to get delegation working for both new jobs and those retrieved from
414
        specific_job = BuildPackageJob(build=self, job=job)
10130.8.8 by William Grant
Provide (I)BuildBase.createBuildQueueEntry (moved from IBuild), and make it work on both implementations.
415
        store.add(specific_job)
416
        return specific_job
417
5608.1.3 by Celso Providelo
applying review comments, r=jml.
418
    def _parseDependencyToken(self, token):
419
        """Parse the given token.
420
421
        Raises AssertionError if the given token couldn't be parsed.
422
423
        Return a triple containing the corresponding (name, version,
424
        relation) for the given dependency token.
425
        """
426
        # XXX cprov 2006-02-27: it may not work for and'd and or'd syntax.
427
        try:
428
            name, version, relation = token[0]
429
        except ValueError:
430
            raise AssertionError(
431
                "APT is not dealing correctly with a dependency token "
432
                "'%r' from %s (%s) with the following dependencies: %s\n"
433
                "It is expected to be a tuple containing only another "
434
                "tuple with 3 elements  (name, version, relation)."
8615.7.1 by Celso Providelo
Fixing typo in IBuild.updateDependencies().
435
                % (token, self.title, self.id, self.dependencies))
14514.3.1 by Colin Watson
Port to new python-apt API.
436
        # Map relations to the canonical form used in control files.
437
        if relation == '<':
438
            relation = '<<'
439
        elif relation == '>':
440
            relation = '>>'
5608.1.3 by Celso Providelo
applying review comments, r=jml.
441
        return (name, version, relation)
442
443
    def _checkDependencyVersion(self, available, required, relation):
444
        """Return True if the available version satisfies the context."""
445
        # This dict maps the package version relationship syntax in lambda
446
        # functions which returns boolean according the results of
14514.3.1 by Colin Watson
Port to new python-apt API.
447
        # apt_pkg.version_compare function (see the order above).
5608.1.3 by Celso Providelo
applying review comments, r=jml.
448
        # For further information about pkg relationship syntax see:
449
        #
450
        # http://www.debian.org/doc/debian-policy/ch-relationships.html
451
        #
452
        version_relation_map = {
453
            # any version is acceptable if no relationship is given
454
            '': lambda x: True,
14514.3.1 by Colin Watson
Port to new python-apt API.
455
            # strictly later
5608.1.3 by Celso Providelo
applying review comments, r=jml.
456
            '>>': lambda x: x == 1,
457
            # later or equal
458
            '>=': lambda x: x >= 0,
14514.3.1 by Colin Watson
Port to new python-apt API.
459
            # strictly equal
5608.1.3 by Celso Providelo
applying review comments, r=jml.
460
            '=': lambda x: x == 0,
461
            # earlier or equal
462
            '<=': lambda x: x <= 0,
463
            # strictly earlier
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
464
            '<<': lambda x: x == -1,
5608.1.3 by Celso Providelo
applying review comments, r=jml.
465
            }
466
467
        # Use apt_pkg function to compare versions
468
        # it behaves similar to cmp, i.e. returns negative
469
        # if first < second, zero if first == second and
470
        # positive if first > second.
14514.3.1 by Colin Watson
Port to new python-apt API.
471
        dep_result = apt_pkg.version_compare(available, required)
5608.1.3 by Celso Providelo
applying review comments, r=jml.
472
473
        return version_relation_map[relation](dep_result)
474
475
    def _isDependencySatisfied(self, token):
476
        """Check if the given dependency token is satisfied.
477
11149.9.12 by William Grant
Trim unnecessary ogre model restriction from _isDependencySatisfied; it's now handled by findDepCandidateByName.
478
        Check if the dependency exists and that its version constraint is
479
        satisfied.
5608.1.3 by Celso Providelo
applying review comments, r=jml.
480
        """
481
        name, version, relation = self._parseDependencyToken(token)
5985.4.1 by Celso Providelo
Moving binary dependency lookup methods from DistroArchSeries to Archive.
482
11149.9.19 by William Grant
Replace findDepCandidateByName with findDepCandidates, now returning all matching publications. Tests updated, and _isDependencySatisfied now checks if any publications satisfy its version criteria. Added tests for versioned dependency behaviour.
483
        # There may be several published versions in the available
484
        # archives and pockets. If any one of them satisifies our
485
        # constraints, the dependency is satisfied.
486
        dep_candidates = self.archive.findDepCandidates(
11149.9.10 by William Grant
Fix _isDependencySatisfied's fDCBN call. Tests now pass.
487
            self.distro_arch_series, self.pocket, self.current_component,
488
            self.source_package_release.sourcepackagename.name, name)
5608.1.3 by Celso Providelo
applying review comments, r=jml.
489
11149.9.19 by William Grant
Replace findDepCandidateByName with findDepCandidates, now returning all matching publications. Tests updated, and _isDependencySatisfied now checks if any publications satisfy its version criteria. Added tests for versioned dependency behaviour.
490
        for dep_candidate in dep_candidates:
491
            if self._checkDependencyVersion(
492
                dep_candidate.binarypackagerelease.version, version,
493
                relation):
494
                return True
5608.1.3 by Celso Providelo
applying review comments, r=jml.
495
11149.9.19 by William Grant
Replace findDepCandidateByName with findDepCandidates, now returning all matching publications. Tests updated, and _isDependencySatisfied now checks if any publications satisfy its version criteria. Added tests for versioned dependency behaviour.
496
        return False
5608.1.3 by Celso Providelo
applying review comments, r=jml.
497
498
    def _toAptFormat(self, token):
499
        """Rebuild dependencies line in apt format."""
500
        name, version, relation = self._parseDependencyToken(token)
501
        if relation and version:
502
            return '%s (%s %s)' % (name, relation, version)
503
        return '%s' % name
504
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
505
    def updateDependencies(self):
506
        """See `IBuild`."""
5608.1.2 by Celso Providelo
applying review comments, r=jml.
507
14514.3.1 by Colin Watson
Port to new python-apt API.
508
        # apt_pkg requires init_system to get version_compare working
509
        # properly.
510
        apt_pkg.init_system()
5608.1.2 by Celso Providelo
applying review comments, r=jml.
511
512
        # Check package build dependencies using apt_pkg
513
        try:
14514.3.1 by Colin Watson
Port to new python-apt API.
514
            parsed_deps = apt_pkg.parse_depends(self.dependencies)
5608.1.2 by Celso Providelo
applying review comments, r=jml.
515
        except (ValueError, TypeError):
12259.1.1 by Julian Edwards
Make buildd-retry-depwait skip over binaries with bad dependencies instead of crashing.
516
            raise UnparsableDependencies(
5608.1.2 by Celso Providelo
applying review comments, r=jml.
517
                "Build dependencies for %s (%s) could not be parsed: '%s'\n"
518
                "It indicates that something is wrong in buildd-slaves."
8615.7.1 by Celso Providelo
Fixing typo in IBuild.updateDependencies().
519
                % (self.title, self.id, self.dependencies))
5608.1.2 by Celso Providelo
applying review comments, r=jml.
520
521
        remaining_deps = [
5608.1.3 by Celso Providelo
applying review comments, r=jml.
522
            self._toAptFormat(token) for token in parsed_deps
523
            if not self._isDependencySatisfied(token)]
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
524
525
        # Update dependencies line
7675.687.67 by Michael Nelson
Continued getting test_binarypackagebuild to pass, but stuck on a db view definition.
526
        self.dependencies = u", ".join(remaining_deps)
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
527
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
528
    def __getitem__(self, name):
529
        return self.getBinaryPackageRelease(name)
530
531
    def getBinaryPackageRelease(self, name):
4285.3.65 by Celso Providelo
review comments [r=barry].
532
        """See `IBuild`."""
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
533
        for binpkg in self.binarypackages:
534
            if binpkg.name == name:
535
                return binpkg
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
536
        raise NotFoundError('No binary package "%s" in build' % name)
2705 by Canonical.com Patch Queue Manager
r=spiv, mark's soyuz loving.
537
4456.5.3 by Celso Providelo
Remove BPR.{copyright, licence} usage (except from gina).
538
    def createBinaryPackageRelease(
539
        self, binarypackagename, version, summary, description,
7675.786.3 by Jelmer Vernooij
Add tests for user_defined_fields in BinaryPackageRelease.
540
        binpackageformat, component, section, priority, installedsize,
541
        architecturespecific, shlibdeps=None, depends=None, recommends=None,
542
        suggests=None, conflicts=None, replaces=None, provides=None,
543
        pre_depends=None, enhances=None, breaks=None, essential=False,
7675.805.1 by Jelmer Vernooij
Parse homepage field from binarypackagerelease and sourcepackagerelease control fields.
544
        debug_package=None, user_defined_fields=None, homepage=None):
2713 by Canonical.com Patch Queue Manager
Various fixes to queue, build etc. add zcml for queue, DB patch included. r=stevea,stub. Also fix dbschema security proxy bug (bug 1971) r=stevea
545
        """See IBuild."""
4456.5.3 by Celso Providelo
Remove BPR.{copyright, licence} usage (except from gina).
546
        return BinaryPackageRelease(
547
            build=self, binarypackagename=binarypackagename, version=version,
548
            summary=summary, description=description,
549
            binpackageformat=binpackageformat,
550
            component=component, section=section, priority=priority,
551
            shlibdeps=shlibdeps, depends=depends, recommends=recommends,
552
            suggests=suggests, conflicts=conflicts, replaces=replaces,
5433.2.1 by Celso Providelo
Fixing bug 172308 part 1, populating the new fields in SPR/BPR.
553
            provides=provides, pre_depends=pre_depends, enhances=enhances,
554
            breaks=breaks, essential=essential, installedsize=installedsize,
7675.752.20 by William Grant
Set debug_package at creation time, rather than updating later.
555
            architecturespecific=architecturespecific,
7675.786.3 by Jelmer Vernooij
Add tests for user_defined_fields in BinaryPackageRelease.
556
            debug_package=debug_package,
7675.805.1 by Jelmer Vernooij
Parse homepage field from binarypackagerelease and sourcepackagerelease control fields.
557
            user_defined_fields=user_defined_fields, homepage=homepage)
2713 by Canonical.com Patch Queue Manager
Various fixes to queue, build etc. add zcml for queue, DB patch included. r=stevea,stub. Also fix dbschema security proxy bug (bug 1971) r=stevea
558
10130.8.8 by William Grant
Provide (I)BuildBase.createBuildQueueEntry (moved from IBuild), and make it work on both implementations.
559
    def estimateDuration(self):
11411.7.24 by j.c.sackett
Merged from devel.
560
        """See `IPackageBuild`."""
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
561
        # Always include the primary archive when looking for
562
        # past build times (just in case that none can be found
563
        # in a PPA or copy archive).
564
        archives = [self.archive.id]
565
        if self.archive.purpose != ArchivePurpose.PRIMARY:
7675.687.70 by Michael Nelson
More changes to get test_publishing passing.
566
            archives.append(self.distro_arch_series.main_archive.id)
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
567
568
        # Look for all sourcepackagerelease instances that match the name
569
        # and get the (successfully built) build records for this
570
        # package.
10667.2.2 by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet
571
        completed_builds = BinaryPackageBuild.select("""
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
572
            BinaryPackageBuild.source_package_release =
573
                SourcePackageRelease.id AND
7675.687.59 by Michael Nelson
Updated estimatedDuration to not error.
574
            BinaryPackageBuild.id != %s AND
575
            BinaryPackageBuild.distro_arch_series = %s AND
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
576
            SourcePackageRelease.sourcepackagename = SourcePackageName.id AND
577
            SourcePackageName.name = %s AND
7675.687.59 by Michael Nelson
Updated estimatedDuration to not error.
578
            BinaryPackageBuild.package_build = PackageBuild.id AND
579
            PackageBuild.archive IN %s AND
580
            PackageBuild.build_farm_job = BuildFarmJob.id AND
581
            BuildFarmJob.date_finished IS NOT NULL AND
582
            BuildFarmJob.status = %s
583
            """ % sqlvalues(self, self.distro_arch_series,
584
                            self.source_package_release.name, archives,
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
585
                            BuildStatus.FULLYBUILT),
7675.687.59 by Michael Nelson
Updated estimatedDuration to not error.
586
            orderBy=['-BuildFarmJob.date_finished', '-id'],
587
            clauseTables=['PackageBuild', 'BuildFarmJob', 'SourcePackageName',
588
                          'SourcePackageRelease'])
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
589
10976.1.2 by Michael Nelson
Don't fall over if duration cannot be calculated.
590
        estimated_duration = None
12180.1.6 by Julian Edwards
Fix unnecessary .count()s in model/binarypackagebuild.py
591
        if bool(completed_builds):
10976.1.2 by Michael Nelson
Don't fall over if duration cannot be calculated.
592
            # Historic build data exists, use the most recent value -
593
            # assuming it has valid data.
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
594
            most_recent_build = completed_builds[0]
10976.1.2 by Michael Nelson
Don't fall over if duration cannot be calculated.
595
            estimated_duration = most_recent_build.duration
596
597
        if estimated_duration is None:
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
598
            # Estimate the build duration based on package size if no
599
            # historic build data exists.
600
601
            # Get the package size in KB.
7675.687.59 by Michael Nelson
Updated estimatedDuration to not error.
602
            package_size = self.source_package_release.getPackageSize()
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
603
604
            if package_size > 0:
605
                # Analysis of previous build data shows that a build rate
606
                # of 6 KB/second is realistic. Furthermore we have to add
607
                # another minute for generic build overhead.
13668.1.18 by Curtis Hovey
Hushed lint.
608
                estimate = int(package_size / 6.0 / 60 + 1)
7675.403.2 by Muharem Hrnjadovic
Merged in code/test fixes.
609
            else:
610
                # No historic build times and no package size available,
611
                # assume a build time of 5 minutes.
612
                estimate = 5
613
            estimated_duration = datetime.timedelta(minutes=estimate)
614
615
        return estimated_duration
616
7675.539.17 by William Grant
Add IBuildBase.verifySuccessfulUpload, and use it to replace the binary-specific _handleStatus_OK check.
617
    def verifySuccessfulUpload(self):
12180.1.6 by Julian Edwards
Fix unnecessary .count()s in model/binarypackagebuild.py
618
        return bool(self.binarypackages)
7675.539.17 by William Grant
Add IBuildBase.verifySuccessfulUpload, and use it to replace the binary-specific _handleStatus_OK check.
619
3804.1.44 by Celso Providelo
Sort out FAILEDTOUPLOAD build notifications and add extra tests.
620
    def notify(self, extra_info=None):
11411.7.24 by j.c.sackett
Merged from devel.
621
        """See `IPackageBuild`.
10143.2.11 by William Grant
Add IBuildBase.{is_private,notify}, and stop a few more methods from violating the interface.
622
623
        If config.buildmaster.build_notification is disable, simply
624
        return.
625
626
        If config.builddmaster.notify_owner is enabled and SPR.creator
627
        has preferredemail it will send an email to the creator, Bcc:
628
        to the config.builddmaster.default_recipient. If one of the
629
        conditions was not satisfied, no preferredemail found (autosync
630
        or untouched packages from debian) or config options disabled,
631
        it will only send email to the specified default recipient.
632
633
        This notification will contain useful information about
634
        the record in question (all states are supported), see
635
        doc/build-notification.txt for further information.
636
        """
637
3686.3.4 by Celso Providelo
applying review comments
638
        if not config.builddmaster.send_build_notification:
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
639
            return
12221.13.17 by Aaron Bentley
Fix success emails.
640
        if self.status == BuildStatus.FULLYBUILT:
641
            return
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
642
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
643
        recipients = set()
644
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
645
        fromaddress = format_address(
646
            config.builddmaster.default_sender_name,
647
            config.builddmaster.default_sender_address)
648
649
        extra_headers = {
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
650
            'X-Launchpad-Build-State': self.status.name,
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
651
            'X-Launchpad-Build-Component': self.current_component.name,
652
            'X-Launchpad-Build-Arch':
10953.1.5 by Julian Edwards
fix lint
653
                self.distro_arch_series.architecturetag,
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
654
            }
655
4664.1.1 by Curtis Hovey
Normalized comments for bug 3732.
656
        # XXX cprov 2006-10-27: Temporary extra debug info about the
3691.447.28 by Celso Providelo
applying review comments (r=thumper).
657
        # SPR.creator in context, to be used during the service quarantine,
658
        # notify_owner will be disabled to avoid *spamming* Debian people.
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
659
        creator = self.source_package_release.creator
3691.447.28 by Celso Providelo
applying review comments (r=thumper).
660
        extra_headers['X-Creator-Recipient'] = ",".join(
7495.2.3 by Curtis Hovey
Renamed contactEmailAddresses => get_contact_email_addresses. Fixed long lines.
661
            get_contact_email_addresses(creator))
3691.447.28 by Celso Providelo
applying review comments (r=thumper).
662
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
663
        # Currently there are 7038 SPR published in edgy which the creators
664
        # have no preferredemail. They are the autosync ones (creator = katie,
665
        # 3583 packages) and the untouched sources since we have migrated from
666
        # DAK (the rest). We should not spam Debian maintainers.
6300.1.1 by Muharem Hrnjadovic
fixed tests
667
668
        # Please note that both the package creator and the package uploader
669
        # will be notified of failures if:
670
        #     * the 'notify_owner' flag is set
671
        #     * the package build (failure) occurred in the original
672
        #       archive.
673
        package_was_not_copied = (
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
674
            self.archive == self.source_package_release.upload_archive)
6300.1.1 by Muharem Hrnjadovic
fixed tests
675
676
        if package_was_not_copied and config.builddmaster.notify_owner:
8432.1.1 by Julian Edwards
Prevent email spam for build failure notifications being sent to package creators when PPA users upload unchanged packages to their PPA.
677
            if (self.archive.is_ppa and creator.inTeam(self.archive.owner)
678
                or
679
                not self.archive.is_ppa):
680
                # If this is a PPA, the package creator should only be
681
                # notified if they are the PPA owner or in the PPA team.
682
                # (see bug 375757)
683
                # Non-PPA notifications inform the creator regardless.
684
                recipients = recipients.union(
685
                    get_contact_email_addresses(creator))
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
686
            dsc_key = self.source_package_release.dscsigningkey
6300.1.1 by Muharem Hrnjadovic
fixed tests
687
            if dsc_key:
688
                recipients = recipients.union(
7495.2.3 by Curtis Hovey
Renamed contactEmailAddresses => get_contact_email_addresses. Fixed long lines.
689
                    get_contact_email_addresses(dsc_key.owner))
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
690
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
691
        # Modify notification contents according the targeted archive.
692
        # 'Archive Tag', 'Subject' and 'Source URL' are customized for PPA.
693
        # We only send build-notifications to 'buildd-admin' celebrity for
694
        # main archive candidates.
695
        # For PPA build notifications we include the archive.owner
696
        # contact_address.
6300.1.1 by Muharem Hrnjadovic
fixed tests
697
        if not self.archive.is_ppa:
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
698
            buildd_admins = getUtility(ILaunchpadCelebrities).buildd_admin
699
            recipients = recipients.union(
7495.2.3 by Curtis Hovey
Renamed contactEmailAddresses => get_contact_email_addresses. Fixed long lines.
700
                get_contact_email_addresses(buildd_admins))
5005.1.2 by Julian Edwards
Trivial amendment to add extra headers to the notification email to include
701
            archive_tag = '%s primary archive' % self.distribution.name
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
702
            subject = "[Build #%d] %s" % (self.id, self.title)
703
            source_url = canonical_url(self.distributionsourcepackagerelease)
704
        else:
705
            recipients = recipients.union(
7495.2.3 by Curtis Hovey
Renamed contactEmailAddresses => get_contact_email_addresses. Fixed long lines.
706
                get_contact_email_addresses(self.archive.owner))
3691.451.10 by Celso Providelo
minor comment fixing (rs=kiko).
707
            # For PPAs we run the risk of having no available contact_address,
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
708
            # for instance, when both, SPR.creator and Archive.owner have
709
            # not enabled it.
710
            if len(recipients) == 0:
711
                return
8137.17.24 by Barry Warsaw
thread merge
712
            archive_tag = '%s PPA' % get_ppa_reference(self.archive)
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
713
            subject = "[Build #%d] %s (%s)" % (
714
                self.id, self.title, archive_tag)
715
            source_url = 'not available'
8137.17.24 by Barry Warsaw
thread merge
716
            extra_headers['X-Launchpad-PPA'] = get_ppa_reference(self.archive)
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
717
4664.1.1 by Curtis Hovey
Normalized comments for bug 3732.
718
        # XXX cprov 2006-08-02: pending security recipients for SECURITY
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
719
        # pocket build. We don't build SECURITY yet :(
720
4664.1.1 by Curtis Hovey
Normalized comments for bug 3732.
721
        # XXX cprov 2006-08-02: find out a way to glue parameters reported
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
722
        # with the state in the build worflow, maybe by having an
723
        # IBuild.statusReport property, which could also be used in the
724
        # respective page template.
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
725
        if self.status in [
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
726
            BuildStatus.NEEDSBUILD, BuildStatus.SUPERSEDED]:
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
727
            # untouched builds
728
            buildduration = 'not available'
729
            buildlog_url = 'not available'
730
            builder_url = 'not available'
11039.2.43 by Jelmer Vernooij
Fix tests.
731
        elif self.status == BuildStatus.UPLOADING:
732
            buildduration = 'uploading'
733
            buildlog_url = 'see builder page'
734
            builder_url = 'not available'
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
735
        elif self.status == BuildStatus.BUILDING:
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
736
            # build in process
737
            buildduration = 'not finished'
738
            buildlog_url = 'see builder page'
739
            builder_url = canonical_url(self.buildqueue_record.builder)
740
        else:
741
            # completed states (success and failure)
742
            buildduration = DurationFormatterAPI(
7675.687.135 by Michael Nelson
buildd-slavescanner.txt and archive-views.txt
743
                self.duration).approximateduration()
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
744
            buildlog_url = self.log_url
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
745
            builder_url = canonical_url(self.builder)
746
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
747
        if self.status == BuildStatus.FAILEDTOUPLOAD:
3804.1.44 by Celso Providelo
Sort out FAILEDTOUPLOAD build notifications and add extra tests.
748
            assert extra_info is not None, (
749
                'Extra information is required for FAILEDTOUPLOAD '
750
                'notifications.')
751
            extra_info = 'Upload log:\n%s' % extra_info
752
        else:
753
            extra_info = ''
754
14538.2.36 by Curtis Hovey
Moved email templates to lp.soyuz
755
        template = get_email_template('build-notification.txt', app='soyuz')
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
756
        replacements = {
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
757
            'source_name': self.source_package_release.name,
758
            'source_version': self.source_package_release.version,
759
            'architecturetag': self.distro_arch_series.architecturetag,
760
            'build_state': self.status.title,
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
761
            'build_duration': buildduration,
762
            'buildlog_url': buildlog_url,
763
            'builder_url': builder_url,
764
            'build_title': self.title,
765
            'build_url': canonical_url(self),
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
766
            'source_url': source_url,
3804.1.44 by Celso Providelo
Sort out FAILEDTOUPLOAD build notifications and add extra tests.
767
            'extra_info': extra_info,
3691.447.27 by Celso Providelo
Customizing build notifications for PPA.
768
            'archive_tag': archive_tag,
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
769
            'component_tag': self.current_component.name,
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
770
            }
771
        message = template % replacements
772
3496.1.95 by Celso Providelo
Send build notification to the launchpad buildd celebrity members/contactaddress, removing default_recipient config option and improving tests.
773
        for toaddress in recipients:
774
            simple_sendmail(
3496.1.96 by Celso Providelo
more elegant way to append maintainer emailaddress to the contactTeamAddresses (already casted to ASCII)
775
                fromaddress, toaddress, subject, message,
3496.1.95 by Celso Providelo
Send build notification to the launchpad buildd celebrity members/contactaddress, removing default_recipient config option and improving tests.
776
                headers=extra_headers)
3686.3.3 by Celso Providelo
Fix bug #31609 (implemetation of soyuz/+spec/build-failure-process, aka build-failure-notification)
777
8636.3.3 by Julian Edwards
Push proxied lfas instead of plain librarian links.
778
    def _getDebByFileName(self, filename):
779
        """Helper function to get a .deb LFA in the context of this build."""
7675.752.19 by William Grant
Add Build.getBinaryPackageFileByName, so we can look up DDEBs.
780
        bpf = self.getBinaryPackageFileByName(filename)
781
        if bpf is not None:
782
            return bpf.libraryfile
783
        else:
784
            return None
8636.3.3 by Julian Edwards
Push proxied lfas instead of plain librarian links.
785
7077.2.6 by Celso Providelo
Spliting IArchive & IBuild getFileByName(), both used to traverse on +files/<filename> to StreamOrRedirectLibraryFileAliasView.
786
    def getFileByName(self, filename):
787
        """See `IBuild`."""
788
        if filename.endswith('.changes'):
8537.6.1 by Celso Providelo
Re-implementing the PackageUpload lookups on SourcePackageRelese and Build in preparation to soyuz-delayed-copies.
789
            file_object = self.upload_changesfile
7077.2.6 by Celso Providelo
Spliting IArchive & IBuild getFileByName(), both used to traverse on +files/<filename> to StreamOrRedirectLibraryFileAliasView.
790
        elif filename.endswith('.txt.gz'):
7675.687.80 by Michael Nelson
Update to get doc/archive-files.txt passing.
791
            file_object = self.log
7077.2.6 by Celso Providelo
Spliting IArchive & IBuild getFileByName(), both used to traverse on +files/<filename> to StreamOrRedirectLibraryFileAliasView.
792
        elif filename.endswith('_log.txt'):
793
            file_object = self.upload_log
8636.3.3 by Julian Edwards
Push proxied lfas instead of plain librarian links.
794
        elif filename.endswith('deb'):
795
            file_object = self._getDebByFileName(filename)
7077.2.6 by Celso Providelo
Spliting IArchive & IBuild getFileByName(), both used to traverse on +files/<filename> to StreamOrRedirectLibraryFileAliasView.
796
        else:
7176.1.1 by Celso Providelo
Fixing #282694 (404 instead of oopsing on unsuported archive filename/extension lookups), r=bigjools.
797
            raise NotFoundError(filename)
7077.2.6 by Celso Providelo
Spliting IArchive & IBuild getFileByName(), both used to traverse on +files/<filename> to StreamOrRedirectLibraryFileAliasView.
798
7077.2.8 by Celso Providelo
Testing ...
799
        if file_object is not None and file_object.filename == filename:
800
            return file_object
801
802
        raise NotFoundError(filename)
803
7675.752.19 by William Grant
Add Build.getBinaryPackageFileByName, so we can look up DDEBs.
804
    def getBinaryPackageFileByName(self, filename):
805
        """See `IBuild`."""
806
        return Store.of(self).find(
807
            BinaryPackageFile,
808
            BinaryPackageRelease.build == self.id,
809
            BinaryPackageFile.binarypackagerelease == BinaryPackageRelease.id,
810
            LibraryFileAlias.id == BinaryPackageFile.libraryfileID,
811
            LibraryFileAlias.filename == filename).one()
812
11005.3.13 by Michael Nelson
Ensure calling getSpecificJob on a binary is a noop.
813
    def getSpecificJob(self):
814
        """See `IBuildFarmJob`."""
815
        # If we are asked to adapt an object that is already a binary
816
        # package build, then don't hit the db.
817
        return self
818
11039.3.18 by Jelmer Vernooij
Fix sprb test.
819
    def getUploader(self, changes):
820
        """See `IBinaryPackageBuild`."""
821
        return changes.signer
822
1670 by Canonical.com Patch Queue Manager
Big lot of database clean-up r=stub except for resolution of conflicts.
823
10667.2.2 by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet
824
class BinaryPackageBuildSet:
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
825
    implements(IBinaryPackageBuildSet)
1670 by Canonical.com Patch Queue Manager
Big lot of database clean-up r=stub except for resolution of conflicts.
826
7675.687.48 by Michael Nelson
Initial update of binarypackagebuild to use new table, replaced calculated_buildstart with build_started.
827
    def new(self, distro_arch_series, source_package_release, processor,
828
            archive, pocket, status=BuildStatus.NEEDSBUILD,
829
            date_created=None):
830
        """See `IBinaryPackageBuildSet`."""
831
        # Create the PackageBuild to which the new BinaryPackageBuild
832
        # will delegate.
833
        package_build = getUtility(IPackageBuildSource).new(
834
            BinaryPackageBuild.build_farm_job_type,
835
            archive.require_virtualized, archive, pocket, processor,
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
836
            status, date_created=date_created)
7675.687.48 by Michael Nelson
Initial update of binarypackagebuild to use new table, replaced calculated_buildstart with build_started.
837
838
        binary_package_build = BinaryPackageBuild(
839
            package_build=package_build,
840
            distro_arch_series=distro_arch_series,
841
            source_package_release=source_package_release)
842
        return binary_package_build
843
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
844
    def getBuildBySRAndArchtag(self, sourcepackagereleaseID, archtag):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
845
        """See `IBinaryPackageBuildSet`"""
5121.2.6 by Stuart Bishop
Some required code updates
846
        clauseTables = ['DistroArchSeries']
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
847
        query = ('BinaryPackageBuild.source_package_release = %s '
848
                 'AND BinaryPackageBuild.distro_arch_series = '
849
                     'DistroArchSeries.id '
5121.2.6 by Stuart Bishop
Some required code updates
850
                 'AND DistroArchSeries.architecturetag = %s'
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
851
                 % sqlvalues(sourcepackagereleaseID, archtag))
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
852
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
853
        return BinaryPackageBuild.select(query, clauseTables=clauseTables)
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
854
12961.1.2 by William Grant
BinaryPackageBuildSet.getByBuildID -> getByID.
855
    def getByID(self, id):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
856
        """See `IBinaryPackageBuildSet`."""
4271.4.4 by Julian Edwards
Address review comments and amend existing tests to work with the new
857
        try:
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
858
            return BinaryPackageBuild.get(id)
4271.4.4 by Julian Edwards
Address review comments and amend existing tests to work with the new
859
        except SQLObjectNotFound, e:
860
            raise NotFoundError(str(e))
2713 by Canonical.com Patch Queue Manager
Various fixes to queue, build etc. add zcml for queue, DB patch included. r=stevea,stub. Also fix dbschema security proxy bug (bug 1971) r=stevea
861
12961.1.5 by William Grant
Add ISpecificBuildFarmJobSource, which TTBS/SPRB/BPBS already basically implemented. Register them like ISpecificBuildFarmJob: with the BuildFarmJobType as the name.
862
    def getByBuildFarmJob(self, build_farm_job):
863
        """See `ISpecificBuildFarmJobSource`."""
12961.1.7 by William Grant
Drop ISpecificBuildFarmJob implementations.
864
        find_spec = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
865
        resulting_tuple = Store.of(build_farm_job).find(
866
            find_spec,
867
            BinaryPackageBuild.package_build == PackageBuild.id,
868
            PackageBuild.build_farm_job == BuildFarmJob.id,
869
            BuildFarmJob.id == build_farm_job.id).one()
870
        if resulting_tuple is None:
871
            return None
872
        return resulting_tuple[0]
12961.1.5 by William Grant
Add ISpecificBuildFarmJobSource, which TTBS/SPRB/BPBS already basically implemented. Register them like ISpecificBuildFarmJob: with the BuildFarmJobType as the name.
873
14513.2.1 by Raphael Badin
Preload build data prior to displaying the builders homepage.
874
    def preloadBuildsData(self, builds):
875
        # Circular imports.
876
        from lp.soyuz.model.distroarchseries import (
877
            DistroArchSeries
878
            )
879
        from lp.registry.model.distroseries import (
880
            DistroSeries
881
            )
882
        from lp.registry.model.distribution import (
883
            Distribution
884
            )
885
        from lp.soyuz.model.archive import Archive
886
        from lp.registry.model.person import Person
887
        self._prefetchBuildData(builds)
888
        distro_arch_series = load_related(
889
            DistroArchSeries, builds, ['distro_arch_series_id'])
890
        package_builds = load_related(
891
            PackageBuild, builds, ['package_build_id'])
892
        archives = load_related(Archive, package_builds, ['archive_id'])
893
        load_related(Person, archives, ['ownerID'])
894
        distroseries = load_related(
895
            DistroSeries, distro_arch_series, ['distroseriesID'])
896
        load_related(
897
            Distribution, distroseries, ['distributionID'])
898
14265.3.1 by Raphael Badin
Add getSpecificJobs to load jobs in batches.
899
    def getByBuildFarmJobs(self, build_farm_jobs):
900
        """See `ISpecificBuildFarmJobSource`."""
901
        if len(build_farm_jobs) == 0:
902
            return EmptyResultSet()
903
        clause_tables = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
904
        build_farm_job_ids = [
905
            build_farm_job.id for build_farm_job in build_farm_jobs]
14265.5.1 by Raphael Badin
Eager load stuff.
906
907
        resultset = Store.of(build_farm_jobs[0]).using(*clause_tables).find(
14265.3.1 by Raphael Badin
Add getSpecificJobs to load jobs in batches.
908
            BinaryPackageBuild,
909
            BinaryPackageBuild.package_build == PackageBuild.id,
910
            PackageBuild.build_farm_job == BuildFarmJob.id,
911
            BuildFarmJob.id.is_in(build_farm_job_ids))
14513.2.1 by Raphael Badin
Preload build data prior to displaying the builders homepage.
912
        return DecoratedResultSet(
913
            resultset, pre_iter_hook=self.preloadBuildsData)
14265.3.1 by Raphael Badin
Add getSpecificJobs to load jobs in batches.
914
9760.8.1 by Brad Crittenden
Change the non-English 'serieses' to 'series' throughout our codebase.
915
    def getPendingBuildsForArchSet(self, archseries):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
916
        """See `IBinaryPackageBuildSet`."""
9760.8.1 by Brad Crittenden
Change the non-English 'serieses' to 'series' throughout our codebase.
917
        if not archseries:
3691.93.27 by Christian Reis
Factor the builddmaster script into a buildmaster directory, splitting out the classes into their own modules. Make sure the buildd-* scripts run based on sampledata (they broke). Make sorting of releases in queue-builder stable. Moved a warning from the slave scanner script into the build master and clean up test instance of same code. Update tests to cope with new locations.
918
            return None
919
9760.8.1 by Brad Crittenden
Change the non-English 'serieses' to 'series' throughout our codebase.
920
        archseries_ids = [d.id for d in archseries]
7675.687.130 by Michael Nelson
Fixes for test_buildd_cronscripts.py
921
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
922
        return store.find(
923
            BinaryPackageBuild,
7675.166.301 by Stuart Bishop
Replace In(col, i) with col.is_in(u) to work around Bug #670906 and delint
924
            BinaryPackageBuild.distro_arch_series_id.is_in(archseries_ids),
7675.687.130 by Michael Nelson
Fixes for test_buildd_cronscripts.py
925
            BinaryPackageBuild.package_build == PackageBuild.id,
926
            PackageBuild.build_farm_job == BuildFarmJob.id,
927
            BuildFarmJob.status == BuildStatus.NEEDSBUILD)
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
928
8730.4.13 by Michael Nelson
Updated ISourcePackage.getBuildRecords() to reuse IBuildSet.handleOptionalParamsForBuildQueries().
929
    def handleOptionalParamsForBuildQueries(
8730.4.8 by Michael Nelson
Added support for arch_tag in IBuildSet.getBuildsForArchive() and underlying _handleOptionalParams().
930
        self, queries, tables, status=None, name=None, pocket=None,
931
        arch_tag=None):
8730.4.21 by Michael Nelson
Removed handleOptionalParamsForBuildQueries() from the IBuildSet interface (keeping it on the content class).
932
        """Construct query clauses needed/shared by all getBuild..() methods.
933
934
        This method is not exposed via the public interface as it is only
8730.4.24 by Michael Nelson
Removed lint.
935
        used to DRY-up trusted code.
8730.4.21 by Michael Nelson
Removed handleOptionalParamsForBuildQueries() from the IBuildSet interface (keeping it on the content class).
936
937
        :param queries: container to which to add any resulting query clauses.
938
        :param tables: container to which to add joined tables.
939
        :param status: optional build state for which to add a query clause if
940
            present.
13636.4.2 by Raphael Badin
Also limit the checks to the optional source names selected for the initialization.
941
        :param name: optional source package release name (or list of source
942
            package release names) for which to add a query clause if
943
            present.
944
        :param pocket: optional pocket (or list of pockets) for which to add a
13636.4.1 by Raphael Badin
Expand IDS checks to the pockets copied, limit IDS checks to the architectures copied.
945
            query clause if present.
8730.4.21 by Michael Nelson
Removed handleOptionalParamsForBuildQueries() from the IBuildSet interface (keeping it on the content class).
946
        :param arch_tag: optional architecture tag for which to add a
947
            query clause if present.
948
        """
6916.2.2 by Muharem Hrnjadovic
next refactoring step
949
7675.687.61 by Michael Nelson
Updated to get test_getBuildsForBuilder_no_params passing.
950
        # Ensure the underlying buildfarmjob and package build tables
951
        # are included.
952
        queries.append('BinaryPackageBuild.package_build = PackageBuild.id')
953
        queries.append('PackageBuild.build_farm_job = BuildFarmJob.id')
954
        tables.extend(['PackageBuild', 'BuildFarmJob'])
955
6916.2.2 by Muharem Hrnjadovic
next refactoring step
956
        # Add query clause that filters on build state if the latter is
957
        # provided.
958
        if status is not None:
7675.687.61 by Michael Nelson
Updated to get test_getBuildsForBuilder_no_params passing.
959
            queries.append('BuildFarmJob.status=%s' % sqlvalues(status))
6916.2.2 by Muharem Hrnjadovic
next refactoring step
960
961
        # Add query clause that filters on pocket if the latter is provided.
962
        if pocket:
13636.4.11 by Raphael Badin
Use isinstance(arch_tag, (list, tuple) instead of isinstance(arch_tag, collections.Sequence.
963
            if not isinstance(pocket, (list, tuple)):
13636.4.1 by Raphael Badin
Expand IDS checks to the pockets copied, limit IDS checks to the architectures copied.
964
                pocket = (pocket,)
965
966
            queries.append('PackageBuild.pocket IN %s' % sqlvalues(pocket))
6916.2.2 by Muharem Hrnjadovic
next refactoring step
967
8730.4.8 by Michael Nelson
Added support for arch_tag in IBuildSet.getBuildsForArchive() and underlying _handleOptionalParams().
968
        # Add query clause that filters on architecture tag if provided.
969
        if arch_tag is not None:
970
            queries.append('''
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
971
                BinaryPackageBuild.distro_arch_series = DistroArchSeries.id
972
                AND DistroArchSeries.architecturetag = %s
8730.4.8 by Michael Nelson
Added support for arch_tag in IBuildSet.getBuildsForArchive() and underlying _handleOptionalParams().
973
            ''' % sqlvalues(arch_tag))
974
            tables.extend(['DistroArchSeries'])
975
6916.2.2 by Muharem Hrnjadovic
next refactoring step
976
        # Add query clause that filters on source package release name if the
977
        # latter is provided.
978
        if name is not None:
13636.4.11 by Raphael Badin
Use isinstance(arch_tag, (list, tuple) instead of isinstance(arch_tag, collections.Sequence.
979
            if not isinstance(name, (list, tuple)):
13636.4.2 by Raphael Badin
Also limit the checks to the optional source names selected for the initialization.
980
                queries.append('''
981
                    BinaryPackageBuild.source_package_release =
982
                        SourcePackageRelease.id AND
983
                    SourcePackageRelease.sourcepackagename =
984
                        SourcePackageName.id
985
                    AND SourcepackageName.name LIKE '%%' || %s || '%%'
986
                ''' % quote_like(name))
987
            else:
988
                queries.append('''
989
                    BinaryPackageBuild.source_package_release =
990
                        SourcePackageRelease.id AND
991
                    SourcePackageRelease.sourcepackagename =
992
                        SourcePackageName.id
993
                    AND SourcepackageName.name IN %s
994
                ''' % sqlvalues(name))
7604.5.3 by Muharem Hrnjadovic
optimized second query
995
            tables.extend(['SourcePackageRelease', 'SourcePackageName'])
7604.5.2 by Muharem Hrnjadovic
optimized first query
996
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
997
    def getBuildsForBuilder(self, builder_id, status=None, name=None,
8730.4.16 by Michael Nelson
Fixing tests after refactoring to ensure arg order was consistent.
998
                            arch_tag=None, user=None):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
999
        """See `IBinaryPackageBuildSet`."""
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1000
        queries = []
1001
        clauseTables = []
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1002
8730.4.13 by Michael Nelson
Updated ISourcePackage.getBuildRecords() to reuse IBuildSet.handleOptionalParamsForBuildQueries().
1003
        self.handleOptionalParamsForBuildQueries(
8730.4.16 by Michael Nelson
Fixing tests after refactoring to ensure arg order was consistent.
1004
            queries, clauseTables, status, name, pocket=None,
1005
            arch_tag=arch_tag)
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1006
7333.1.1 by Julian Edwards
Prevent any build listing pages from showing builds that the user is not allowed to see.
1007
        # This code MUST match the logic in the Build security adapter,
1008
        # otherwise users are likely to get 403 errors, or worse.
7675.687.61 by Michael Nelson
Updated to get test_getBuildsForBuilder_no_params passing.
1009
        queries.append("Archive.id = PackageBuild.archive")
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
1010
        clauseTables.append('Archive')
1011
        if user is not None:
7333.1.1 by Julian Edwards
Prevent any build listing pages from showing builds that the user is not allowed to see.
1012
            if not user.inTeam(getUtility(ILaunchpadCelebrities).admin):
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
1013
                queries.append("""
5565.5.16 by Julian Edwards
Some of salgado's review comments applied. Add a new security adapter
1014
                (Archive.private = FALSE
1015
                 OR %s IN (SELECT TeamParticipation.person
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
1016
                       FROM TeamParticipation
5565.5.16 by Julian Edwards
Some of salgado's review comments applied. Add a new security adapter
1017
                       WHERE TeamParticipation.person = %s
1018
                           AND TeamParticipation.team = Archive.owner)
1019
                )""" % sqlvalues(user, user))
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
1020
        else:
1021
            queries.append("Archive.private = FALSE")
1022
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1023
        queries.append("builder=%s" % builder_id)
1024
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1025
        return BinaryPackageBuild.select(
1026
            " AND ".join(queries), clauseTables=clauseTables,
7675.687.61 by Michael Nelson
Updated to get test_getBuildsForBuilder_no_params passing.
1027
            orderBy=["-BuildFarmJob.date_finished", "id"])
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1028
4285.3.65 by Celso Providelo
review comments [r=barry].
1029
    def getBuildsForArchive(self, archive, status=None, name=None,
8730.4.8 by Michael Nelson
Added support for arch_tag in IBuildSet.getBuildsForArchive() and underlying _handleOptionalParams().
1030
                            pocket=None, arch_tag=None):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1031
        """See `IBinaryPackageBuildSet`."""
4285.3.6 by Celso Providelo
IArchive {+edit, +admin, +builds}. Also supports new IArchive fields.
1032
        queries = []
1033
        clauseTables = []
1034
8730.4.13 by Michael Nelson
Updated ISourcePackage.getBuildRecords() to reuse IBuildSet.handleOptionalParamsForBuildQueries().
1035
        self.handleOptionalParamsForBuildQueries(
8730.4.8 by Michael Nelson
Added support for arch_tag in IBuildSet.getBuildsForArchive() and underlying _handleOptionalParams().
1036
            queries, clauseTables, status, name, pocket, arch_tag)
4285.3.6 by Celso Providelo
IArchive {+edit, +admin, +builds}. Also supports new IArchive fields.
1037
1038
        # Ordering according status
1039
        # * SUPERSEDED & All by -datecreated
1040
        # * FULLYBUILT & FAILURES by -datebuilt
1041
        # It should present the builds in a more natural order.
1042
        if status == BuildStatus.SUPERSEDED or status is None:
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1043
            orderBy = ["-BuildFarmJob.date_created"]
4285.3.6 by Celso Providelo
IArchive {+edit, +admin, +builds}. Also supports new IArchive fields.
1044
        else:
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1045
            orderBy = ["-BuildFarmJob.date_finished"]
6231.1.1 by Muharem Hrnjadovic
build job ordering fix
1046
        # All orders fallback to id if the primary order doesn't succeed
1047
        orderBy.append("id")
4285.3.6 by Celso Providelo
IArchive {+edit, +admin, +builds}. Also supports new IArchive fields.
1048
1049
        queries.append("archive=%s" % sqlvalues(archive))
1050
        clause = " AND ".join(queries)
1051
7923.1.2 by Muharem Hrnjadovic
work in progress: move all the build related prefetching into IBuildSet.
1052
        return self._decorate_with_prejoins(
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1053
            BinaryPackageBuild.select(
1054
                clause, clauseTables=clauseTables, orderBy=orderBy))
4285.3.6 by Celso Providelo
IArchive {+edit, +admin, +builds}. Also supports new IArchive fields.
1055
11316.2.1 by William Grant
getBuildsByArchIds now takes a distribution, and uses its precalculated all_distro_archive_ids rather than joining against Archive. The Archive join makes the query an order of magnitude slower.
1056
    def getBuildsByArchIds(self, distribution, arch_ids, status=None,
1057
                           name=None, pocket=None):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1058
        """See `IBinaryPackageBuildSet`."""
12156.9.1 by Steve Kowalik
Kill build-views.txt with fire, and convert it to unit testing.
1059
        # If no distroarchseries were passed in, return an empty list
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
1060
        if not arch_ids:
11177.1.1 by Robert Collins
Delete cruft.
1061
            return EmptyResultSet()
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
1062
3054.1.3 by Celso Providelo
Order IHasBuildRecords.getBuildRecords in NEEDSBUILD state by score value, instead of the default '-datecreated' (valid for the other states), added some tests. Also removed some annoying trailing space in the tests.
1063
        clauseTables = []
1064
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
1065
        # format clause according single/multiple architecture(s) form
1066
        if len(arch_ids) == 1:
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1067
            condition_clauses = [('distro_arch_series=%s'
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
1068
                                  % sqlvalues(arch_ids[0]))]
1069
        else:
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1070
            condition_clauses = [('distro_arch_series IN %s'
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
1071
                                  % sqlvalues(arch_ids))]
1072
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1073
        condition_clauses.extend([
1074
            "BinaryPackageBuild.package_build = PackageBuild.id",
11626.3.10 by Curtis Hovey
Hush lints epic complaints about the changes files.
1075
            "PackageBuild.build_farm_job = BuildFarmJob.id"])
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1076
4664.1.1 by Curtis Hovey
Normalized comments for bug 3732.
1077
        # XXX cprov 2006-09-25: It would be nice if we could encapsulate
3147.5.43 by Celso Providelo
review comments, r=spiv
1078
        # the chunk of code below (which deals with the optional paramenters)
1079
        # and share it with ISourcePackage.getBuildRecords()
1080
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1081
        # exclude gina-generated and security (dak-made) builds
7675.687.83 by Michael Nelson
Intermediate changes for build-failedtoupload-workflow.txt, but need to
1082
        # status == FULLYBUILT && datebuilt == null
7604.5.3 by Muharem Hrnjadovic
optimized second query
1083
        if status == BuildStatus.FULLYBUILT:
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1084
            condition_clauses.append("BuildFarmJob.date_finished IS NOT NULL")
7604.5.3 by Muharem Hrnjadovic
optimized second query
1085
        else:
1086
            condition_clauses.append(
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1087
                "(BuildFarmJob.status <> %s OR "
1088
                " BuildFarmJob.date_finished IS NOT NULL)"
7604.5.3 by Muharem Hrnjadovic
optimized second query
1089
                % sqlvalues(BuildStatus.FULLYBUILT))
3032.1.5 by Celso Providelo
Trully prevent gina generated builds to be presented.
1090
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1091
        # Ordering according status
11039.2.47 by Jelmer Vernooij
Display uploading builds in counts.
1092
        # * NEEDSBUILD, BUILDING & UPLOADING by -lastscore
14022.5.1 by Abel Deuring
more efficient SQL query for BinaryPackageBuildSet.getBuildsByArchIds(), status variants None and BuildStatus.SUPERSEDED
1093
        # * SUPERSEDED & All by -PackageBuild.build_farm_job
1094
        #   (nearly equivalent to -datecreated, but much more
1095
        #   efficient.)
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1096
        # * FULLYBUILT & FAILURES by -datebuilt
1097
        # It should present the builds in a more natural order.
11039.2.47 by Jelmer Vernooij
Display uploading builds in counts.
1098
        if status in [
1099
            BuildStatus.NEEDSBUILD,
1100
            BuildStatus.BUILDING,
1101
            BuildStatus.UPLOADING]:
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
1102
            order_by = [Desc(BuildQueue.lastscore), BinaryPackageBuild.id]
1103
            order_by_table = BuildQueue
3054.1.3 by Celso Providelo
Order IHasBuildRecords.getBuildRecords in NEEDSBUILD state by score value, instead of the default '-datecreated' (valid for the other states), added some tests. Also removed some annoying trailing space in the tests.
1104
            clauseTables.append('BuildQueue')
7675.391.14 by Muharem Hrnjadovic
Fixing code to make tests pass.
1105
            clauseTables.append('BuildPackageJob')
7675.687.76 by Michael Nelson
Updated to get test_hasbuildrecords passing.
1106
            condition_clauses.append(
1107
                'BuildPackageJob.build = BinaryPackageBuild.id')
7675.391.11 by Muharem Hrnjadovic
Build fixes.
1108
            condition_clauses.append('BuildPackageJob.job = BuildQueue.job')
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1109
        elif status == BuildStatus.SUPERSEDED or status is None:
14022.5.1 by Abel Deuring
more efficient SQL query for BinaryPackageBuildSet.getBuildsByArchIds(), status variants None and BuildStatus.SUPERSEDED
1110
            order_by = [Desc(PackageBuild.build_farm_job_id)]
1111
            order_by_table = PackageBuild
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1112
        else:
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
1113
            order_by = [Desc(BuildFarmJob.date_finished),
1114
                        BinaryPackageBuild.id]
1115
            order_by_table = BuildFarmJob
3147.5.39 by Celso Providelo
Fix ordering in +builds pages as suggested in bug #31392
1116
4664.1.1 by Curtis Hovey
Normalized comments for bug 3732.
1117
        # End of duplication (see XXX cprov 2006-09-25 above).
3147.5.43 by Celso Providelo
review comments, r=spiv
1118
8730.4.13 by Michael Nelson
Updated ISourcePackage.getBuildRecords() to reuse IBuildSet.handleOptionalParamsForBuildQueries().
1119
        self.handleOptionalParamsForBuildQueries(
7604.5.2 by Muharem Hrnjadovic
optimized first query
1120
            condition_clauses, clauseTables, status, name, pocket)
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1121
3691.442.27 by Celso Providelo
applying review comments (r=jamesh)
1122
        # Only pick builds from the distribution's main archive to
1123
        # exclude PPA builds
11316.2.1 by William Grant
getBuildsByArchIds now takes a distribution, and uses its precalculated all_distro_archive_ids rather than joining against Archive. The Archive join makes the query an order of magnitude slower.
1124
        condition_clauses.append(
1125
            "PackageBuild.archive IN %s" %
1126
            sqlvalues(list(distribution.all_distro_archive_ids)))
3147.5.1 by Celso Providelo
Filtering builds also by sourcepackagename
1127
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
1128
        store = Store.of(distribution)
1129
        clauseTables = [BinaryPackageBuild] + clauseTables
1130
        result_set = store.using(*clauseTables).find(
1131
            (BinaryPackageBuild, order_by_table), *condition_clauses)
1132
        result_set.order_by(*order_by)
1133
1134
        def get_bpp(result_row):
1135
            return result_row[0]
1136
7923.1.2 by Muharem Hrnjadovic
work in progress: move all the build related prefetching into IBuildSet.
1137
        return self._decorate_with_prejoins(
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
1138
            DecoratedResultSet(result_set, result_decorator=get_bpp))
7923.1.2 by Muharem Hrnjadovic
work in progress: move all the build related prefetching into IBuildSet.
1139
1140
    def _decorate_with_prejoins(self, result_set):
1141
        """Decorate build records with related data prefetch functionality."""
1142
        # Grab the native storm result set.
13957.5.1 by Abel Deuring
StormRangeFactory: make rough_length safe for SELECT DISTINCT queries; getSliceByIndex() now works with plain Storm ResultSets, not only DecoratedResultSets. BuildRecordsView now uses StormRangeFactory. BinaryPackageBuild.getBuildsByArchIds() uses Storm Columns to order the result set, not plain strings.
1143
        result_set = IResultSet(result_set)
7923.1.2 by Muharem Hrnjadovic
work in progress: move all the build related prefetching into IBuildSet.
1144
        decorated_results = DecoratedResultSet(
7923.1.15 by Muharem Hrnjadovic
added special BuildQueue handling for the GUI
1145
            result_set, pre_iter_hook=self._prefetchBuildData)
7923.1.2 by Muharem Hrnjadovic
work in progress: move all the build related prefetching into IBuildSet.
1146
        return decorated_results
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1147
1148
    def retryDepWaiting(self, distroarchseries):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1149
        """See `IBinaryPackageBuildSet`. """
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1150
        # XXX cprov 20071122: use the root logger once bug 164203 is fixed.
1151
        logger = logging.getLogger('retry-depwait')
1152
1153
        # Get the MANUALDEPWAIT records for all archives.
10953.1.3 by Julian Edwards
Ensure the slave store is used for retry-depwait
1154
        store = ISlaveStore(BinaryPackageBuild)
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
1155
1156
        candidates = store.find(
1157
            BinaryPackageBuild,
1158
            BinaryPackageBuild.distro_arch_series == distroarchseries,
1159
            BinaryPackageBuild.package_build == PackageBuild.id,
1160
            PackageBuild.build_farm_job == BuildFarmJob.id,
1161
            BuildFarmJob.status == BuildStatus.MANUALDEPWAIT)
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1162
10953.1.2 by Julian Edwards
test fixes and materialise the list of retry candidates to reduce queries
1163
        # Materialise the results right away to avoid hitting the
1164
        # database multiple times.
1165
        candidates = list(candidates)
1166
1167
        candidates_count = len(candidates)
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1168
        if candidates_count == 0:
1169
            logger.info("No MANUALDEPWAIT record found.")
1170
            return
1171
1172
        logger.info(
1173
            "Found %d builds in MANUALDEPWAIT state." % candidates_count)
1174
1175
        for build in candidates:
1176
            if not build.can_be_retried:
1177
                continue
10953.1.3 by Julian Edwards
Ensure the slave store is used for retry-depwait
1178
            # We're changing 'build' so make sure we have an object from
1179
            # the master store.
1180
            build = IMasterObject(build)
12259.1.1 by Julian Edwards
Make buildd-retry-depwait skip over binaries with bad dependencies instead of crashing.
1181
            try:
1182
                build.updateDependencies()
1183
            except UnparsableDependencies, e:
1184
                logger.error(e)
1185
                continue
1186
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1187
            if build.dependencies:
6234.2.1 by Muharem Hrnjadovic
log output adjusted as required
1188
                logger.debug(
5152.5.6 by Celso Providelo
Restoring retry-depwait feature as another cronscript and with base methods implemented in IBuild.
1189
                    "Skipping %s: %s" % (build.title, build.dependencies))
1190
                continue
1191
            logger.info("Retrying %s" % build.title)
1192
            build.retry()
1193
            build.buildqueue_record.score()
6534.2.2 by Muharem Hrnjadovic
fixed arc counters code
1194
6586.3.1 by Julian Edwards
Add IBuildSet.getBuildsBySourcePackageRelease()
1195
    def getBuildsBySourcePackageRelease(self, sourcepackagerelease_ids,
1196
                                        buildstate=None):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1197
        """See `IBinaryPackageBuildSet`."""
6586.3.4 by Julian Edwards
Curtis' review comments.
1198
        if (sourcepackagerelease_ids is None or
6586.3.1 by Julian Edwards
Add IBuildSet.getBuildsBySourcePackageRelease()
1199
            len(sourcepackagerelease_ids) == 0):
1200
            return []
12588.1.1 by Robert Collins
Eager load PackageBuild and BuildFarmJob for Person:+uploaded-packages.
1201
        # Circular.
1202
        from lp.soyuz.model.archive import Archive
6586.3.1 by Julian Edwards
Add IBuildSet.getBuildsBySourcePackageRelease()
1203
1204
        query = """
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
1205
            source_package_release IN %s AND
1206
            package_build = packagebuild.id AND
1207
            archive.id = packagebuild.archive AND
1208
            archive.purpose != %s AND
1209
            packagebuild.build_farm_job = buildfarmjob.id
6586.3.5 by Julian Edwards
Fix more boobs in the calculations.
1210
            """ % sqlvalues(sourcepackagerelease_ids, ArchivePurpose.PPA)
6586.3.1 by Julian Edwards
Add IBuildSet.getBuildsBySourcePackageRelease()
1211
1212
        if buildstate is not None:
7675.687.90 by Michael Nelson
Gets rest of build.txt passing.
1213
            query += "AND buildfarmjob.status = %s" % sqlvalues(buildstate)
6586.3.1 by Julian Edwards
Add IBuildSet.getBuildsBySourcePackageRelease()
1214
12588.1.1 by Robert Collins
Eager load PackageBuild and BuildFarmJob for Person:+uploaded-packages.
1215
        resultset = IStore(BinaryPackageBuild).using(
1216
            BinaryPackageBuild, PackageBuild, BuildFarmJob, Archive).find(
1217
            (BinaryPackageBuild, PackageBuild, BuildFarmJob),
1218
            SQL(query))
1219
        resultset.order_by(
1220
            Desc(BuildFarmJob.date_created), BinaryPackageBuild.id)
1221
        return DecoratedResultSet(resultset, operator.itemgetter(0))
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1222
1223
    def getStatusSummaryForBuilds(self, builds):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1224
        """See `IBinaryPackageBuildSet`."""
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1225
        # Create a small helper function to collect the builds for a given
1226
        # list of build states:
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1227
        def collect_builds(*states):
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1228
            wanted = []
1229
            for state in states:
1230
                candidates = [build for build in builds
7675.687.81 by Michael Nelson
Changes to get doc/archive.txt passing.
1231
                                if build.status == state]
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1232
                wanted.extend(candidates)
1233
            return wanted
1234
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1235
        failed = collect_builds(BuildStatus.FAILEDTOBUILD,
1236
                                BuildStatus.MANUALDEPWAIT,
1237
                                BuildStatus.CHROOTWAIT,
1238
                                BuildStatus.FAILEDTOUPLOAD)
1239
        needsbuild = collect_builds(BuildStatus.NEEDSBUILD)
11039.2.47 by Jelmer Vernooij
Display uploading builds in counts.
1240
        building = collect_builds(BuildStatus.BUILDING,
1241
                                  BuildStatus.UPLOADING)
8406.1.1 by Michael Nelson
Fix for bug-375424 that ensures only successful builds are included in the status summary (canceled/superseded builds are ignored.
1242
        successful = collect_builds(BuildStatus.FULLYBUILT)
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1243
7434.5.1 by Michael Nelson
Changes from Abel's review
1244
        # Note: the BuildStatus DBItems are used here to summarize the
1245
        # status of a set of builds:s
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1246
        if len(building) != 0:
1247
            return {
7434.5.3 by Michael Nelson
Changes for abel's second review reply
1248
                'status': BuildSetStatus.BUILDING,
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1249
                'builds': building,
1250
                }
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1251
        elif len(needsbuild) != 0:
1252
            return {
7434.5.3 by Michael Nelson
Changes for abel's second review reply
1253
                'status': BuildSetStatus.NEEDSBUILD,
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1254
                'builds': needsbuild,
1255
                }
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1256
        elif len(failed) != 0:
1257
            return {
7434.5.3 by Michael Nelson
Changes for abel's second review reply
1258
                'status': BuildSetStatus.FAILEDTOBUILD,
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1259
                'builds': failed,
1260
                }
7434.3.2 by Michael Nelson
Added backend changes to archive, build and publishing interfaces to
1261
        else:
1262
            return {
7434.5.3 by Michael Nelson
Changes for abel's second review reply
1263
                'status': BuildSetStatus.FULLYBUILT,
8406.1.1 by Michael Nelson
Fix for bug-375424 that ensures only successful builds are included in the status summary (canceled/superseded builds are ignored.
1264
                'builds': successful,
7434.4.2 by Michael Nelson
Updated with changes suggested by Barry.
1265
                }
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1266
7923.1.20 by Muharem Hrnjadovic
Optimized branch to save one expensive query.
1267
    def _prefetchBuildData(self, results):
7923.1.3 by Muharem Hrnjadovic
made the IBuildSet method that prefetches build related data non-public since it's only used internally
1268
        """Used to pre-populate the cache with build related data.
1269
1270
        When dealing with a group of Build records we can't use the
1271
        prejoin facility to also fetch BuildQueue, SourcePackageRelease
1272
        and LibraryFileAlias records in a single query because the
1273
        result set is too large and the queries time out too often.
1274
7923.1.22 by Muharem Hrnjadovic
fixed docstring
1275
        So this method receives a list of Build instances and fetches the
1276
        corresponding SourcePackageRelease and LibraryFileAlias rows
1277
        (prejoined with the appropriate SourcePackageName and
1278
        LibraryFileContent respectively) as well as builders related to the
1279
        Builds at hand.
7923.1.3 by Muharem Hrnjadovic
made the IBuildSet method that prefetches build related data non-public since it's only used internally
1280
        """
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
1281
        from lp.registry.model.sourcepackagename import (
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1282
            SourcePackageName)
8294.6.1 by Julian Edwards
First stab at code-reorg. Still got a discrepancy on stuff I assigned to registry but not migrated yet.
1283
        from lp.soyuz.model.sourcepackagerelease import (
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1284
            SourcePackageRelease)
7923.1.3 by Muharem Hrnjadovic
made the IBuildSet method that prefetches build related data non-public since it's only used internally
1285
7967.1.1 by Celso Providelo
Fixing test failure.
1286
        # Prefetching is not needed if the original result set is empty.
1287
        if len(results) == 0:
1288
            return
1289
7923.1.20 by Muharem Hrnjadovic
Optimized branch to save one expensive query.
1290
        build_ids = [build.id for build in results]
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1291
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
1292
        origin = (
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1293
            BinaryPackageBuild,
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1294
            LeftJoin(
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1295
                PackageBuild,
1296
                BinaryPackageBuild.package_build == PackageBuild.id),
1297
            LeftJoin(
1298
                BuildFarmJob,
1299
                PackageBuild.build_farm_job == BuildFarmJob.id),
1300
            LeftJoin(
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1301
                SourcePackageRelease,
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1302
                (SourcePackageRelease.id ==
7675.687.70 by Michael Nelson
More changes to get test_publishing passing.
1303
                    BinaryPackageBuild.source_package_release_id)),
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1304
            LeftJoin(
1305
                SourcePackageName,
1306
                SourcePackageName.id
1307
                    == SourcePackageRelease.sourcepackagenameID),
1308
            LeftJoin(LibraryFileAlias,
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1309
                     LibraryFileAlias.id == BuildFarmJob.log_id),
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1310
            LeftJoin(LibraryFileContent,
1311
                     LibraryFileContent.id == LibraryFileAlias.contentID),
7923.1.19 by Muharem Hrnjadovic
Now Builders associated with Builds are prefetched as well
1312
            LeftJoin(
1313
                Builder,
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1314
                Builder.id == BuildFarmJob.builder_id),
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1315
            )
1316
        result_set = store.using(*origin).find(
7923.1.15 by Muharem Hrnjadovic
added special BuildQueue handling for the GUI
1317
            (SourcePackageRelease, LibraryFileAlias, SourcePackageName,
7675.687.63 by Michael Nelson
Updated to get test_getBuildsForArchive_no_params to pass.
1318
             LibraryFileContent, Builder, PackageBuild, BuildFarmJob),
7675.166.301 by Stuart Bishop
Replace In(col, i) with col.is_in(u) to work around Bug #670906 and delint
1319
            BinaryPackageBuild.id.is_in(build_ids))
7864.4.2 by Muharem Hrnjadovic
implemented an extended CompleteBuild class that mimics a Build.
1320
7923.1.23 by Muharem Hrnjadovic
Aaron's review comments
1321
        # Force query execution so that the ancillary data gets fetched
1322
        # and added to StupidCache.
1323
        # We are doing this here because there is no "real" caller of
1324
        # this (pre_iter_hook()) method that will iterate over the
1325
        # result set and force the query execution that way.
7923.1.20 by Muharem Hrnjadovic
Optimized branch to save one expensive query.
1326
        return list(result_set)
7675.391.16 by Muharem Hrnjadovic
Second test passes.
1327
1328
    def getByQueueEntry(self, queue_entry):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1329
        """See `IBinaryPackageBuildSet`."""
7675.391.16 by Muharem Hrnjadovic
Second test passes.
1330
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
1331
        result_set = store.find(
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1332
            BinaryPackageBuild,
1333
            BuildPackageJob.build == BinaryPackageBuild.id,
10020.1.1 by Muharem Hrnjadovic
test failures fixed
1334
            BuildPackageJob.job == BuildQueue.jobID,
1335
            BuildQueue.job == queue_entry.job)
7675.391.16 by Muharem Hrnjadovic
Second test passes.
1336
7675.391.32 by Muharem Hrnjadovic
Result set handling improvements.
1337
        return result_set.one()
10430.5.2 by William Grant
Move IBuildQueueSet.getForBuilds to IBuildSet.getQueueEntriesForBuildIDs, since it's Soyuz-specific.
1338
1339
    def getQueueEntriesForBuildIDs(self, build_ids):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1340
        """See `IBinaryPackageBuildSet`."""
10430.5.2 by William Grant
Move IBuildQueueSet.getForBuilds to IBuildSet.getQueueEntriesForBuildIDs, since it's Soyuz-specific.
1341
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
1342
1343
        origin = (
1344
            BuildPackageJob,
1345
            Join(BuildQueue, BuildPackageJob.job == BuildQueue.jobID),
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1346
            Join(
1347
                BinaryPackageBuild,
1348
                BuildPackageJob.build == BinaryPackageBuild.id),
10430.5.2 by William Grant
Move IBuildQueueSet.getForBuilds to IBuildSet.getQueueEntriesForBuildIDs, since it's Soyuz-specific.
1349
            LeftJoin(
1350
                Builder,
1351
                BuildQueue.builderID == Builder.id),
1352
            )
1353
        result_set = store.using(*origin).find(
1354
            (BuildQueue, Builder, BuildPackageJob),
7675.777.1 by Aaron Bentley
Fix builder history page with recipe builds
1355
            BinaryPackageBuild.id.is_in(build_ids))
10430.5.2 by William Grant
Move IBuildQueueSet.getForBuilds to IBuildSet.getQueueEntriesForBuildIDs, since it's Soyuz-specific.
1356
1357
        return result_set
10430.5.3 by William Grant
Move IBuildQueueSet.calculateCandidates to IBuildSet -- it too is Soyuz-specific.
1358
1359
    def calculateCandidates(self, archseries):
10667.2.1 by Michael Nelson
Renamed files and interface/model class.
1360
        """See `IBinaryPackageBuildSet`."""
10430.5.3 by William Grant
Move IBuildQueueSet.calculateCandidates to IBuildSet -- it too is Soyuz-specific.
1361
        if not archseries:
1362
            raise AssertionError("Given 'archseries' cannot be None/empty.")
1363
1364
        arch_ids = [d.id for d in archseries]
1365
1366
        query = """
7675.687.130 by Michael Nelson
Fixes for test_buildd_cronscripts.py
1367
           BinaryPackageBuild.distro_arch_series IN %s AND
1368
           BinaryPackageBuild.package_build = PackageBuild.id AND
1369
           PackageBuild.build_farm_job = BuildFarmJob.id AND
1370
           BuildFarmJob.status = %s AND
10430.5.3 by William Grant
Move IBuildQueueSet.calculateCandidates to IBuildSet -- it too is Soyuz-specific.
1371
           BuildQueue.job_type = %s AND
1372
           BuildQueue.job = BuildPackageJob.job AND
7675.687.130 by Michael Nelson
Fixes for test_buildd_cronscripts.py
1373
           BuildPackageJob.build = BinaryPackageBuild.id AND
10430.5.3 by William Grant
Move IBuildQueueSet.calculateCandidates to IBuildSet -- it too is Soyuz-specific.
1374
           BuildQueue.builder IS NULL
1375
        """ % sqlvalues(
1376
            arch_ids, BuildStatus.NEEDSBUILD, BuildFarmJobType.PACKAGEBUILD)
1377
1378
        candidates = BuildQueue.select(
7675.687.130 by Michael Nelson
Fixes for test_buildd_cronscripts.py
1379
            query, clauseTables=[
1380
                'BinaryPackageBuild', 'PackageBuild', 'BuildFarmJob',
1381
                'BuildPackageJob'],
10430.5.3 by William Grant
Move IBuildQueueSet.calculateCandidates to IBuildSet -- it too is Soyuz-specific.
1382
            orderBy=['-BuildQueue.lastscore'])
1383
1384
        return candidates