1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#!/usr/bin/python -S
#
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tool for 'mass-retrying' build records.
It supports build collections based distroseries and/or distroarchseries.
"""
__metaclass__ = type
import _pythonpath
from optparse import OptionParser
import sys
from zope.component import getUtility
# Still needed fake import to stop circular imports.
import canonical.launchpad.interfaces
from canonical.database.sqlbase import ISOLATION_LEVEL_READ_COMMITTED
from lp.app.errors import NotFoundError
from canonical.launchpad.scripts import (
execute_zcml_for_scripts, logger_options, logger)
from canonical.lp import initZopeless
from lp.buildmaster.enums import BuildStatus
from lp.registry.interfaces.distribution import IDistributionSet
from lp.registry.interfaces.pocket import PackagePublishingPocket
def main():
parser = OptionParser()
logger_options(parser)
parser.add_option("-d", "--distribution",
dest="distribution", metavar="DISTRIBUTION",
default="ubuntu", help="distribution name")
parser.add_option("-s", "--suite",
dest="suite", metavar="SUITE", default=None,
help="suite name")
parser.add_option("-a", "--architecture",
dest="architecture", metavar="ARCH", default=None,
help="architecture tag")
parser.add_option("-N", "--dry-run", action="store_true",
dest="dryrun", metavar="DRY_RUN", default=False,
help="Whether to treat this as a dry-run or not.")
parser.add_option("-F", "--failed", action="store_true",
dest="failed", default=False,
help="Reset builds in FAILED state.")
parser.add_option("-D", "--dep-wait", action="store_true",
dest="depwait", default=False,
help="Reset builds in DEPWAIT state.")
parser.add_option("-C", "--chroot-wait", action="store_true",
dest="chrootwait", default=False,
help="Reset builds in CHROOTWAIT state.")
(options, args) = parser.parse_args()
log = logger(options, "build-mass-retry")
log.debug("Intitialising connection.")
execute_zcml_for_scripts()
ztm = initZopeless(dbuser="fiera",
isolation=ISOLATION_LEVEL_READ_COMMITTED)
try:
distribution = getUtility(IDistributionSet)[options.distribution]
except NotFoundError, info:
log.error("Distribution not found: %s" % info)
return 1
try:
if options.suite is not None:
series, pocket = distribution.getDistroSeriesAndPocket(
options.suite)
else:
series = distribution.currentseries
pocket = PackagePublishingPocket.RELEASE
except NotFoundError, info:
log.error("Suite not found: %s" % info)
return 1
# store distroseries as the current IHasBuildRecord provider
build_provider = series
if options.architecture:
try:
dar = series[options.architecture]
except NotFoundError, info:
log.error(info)
return 1
# store distroarchseries as the current IHasBuildRecord provider
build_provider = dar
log.info("Initializing Build Mass-Retry for '%s/%s'"
% (build_provider.title, pocket.name))
requested_states_map = {
BuildStatus.FAILEDTOBUILD : options.failed,
BuildStatus.MANUALDEPWAIT : options.depwait,
BuildStatus.CHROOTWAIT : options.chrootwait,
}
# XXX cprov 2006-08-31: one query per requested state
# could organise it in a single one nicely if I have
# an empty SQLResult instance, than only iteration + union()
# would work.
for target_state, requested in requested_states_map.items():
if not requested:
continue
log.info("Processing builds in '%s'" % target_state.title)
target_builds = build_provider.getBuildRecords(
build_state=target_state, pocket=pocket)
for build in target_builds:
# Skip builds for superseded sources; they won't ever
# actually build.
if not build.current_source_publication:
log.debug(
'Skipping superseded %s (%s)' % (build.title, build.id))
continue
if not build.can_be_retried:
log.warn('Can not retry %s (%s)' % (build.title, build.id))
continue
log.info('Retrying %s (%s)' % (build.title, build.id))
build.retry()
log.info("Success.")
if options.dryrun:
ztm.abort()
log.info('Dry-run.')
else:
ztm.commit()
log.info("Committed")
return 0
if __name__ == '__main__':
sys.exit(main())
|