~ubuntu-dev/ubuntu-dev-tools/trunk

139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
1
#!/usr/bin/python
2
# 
3
#   buildd - command line interface for Launchpad buildd operations.
4
#
5
#   Copyright (C) 2007 Canonical Ltd.
161 by Jonathan Patrick Davies
* buildd:
6
#   Authors:
7
#    - Martin Pitt <martin.pitt@canonical.com>
8
#    - Jonathan Patrick Davies <jpds@ubuntu.com>
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
9
#
10
#   This program is free software: you can redistribute it and/or modify
11
#   it under the terms of the GNU General Public License as published by
12
#   the Free Software Foundation, either version 3 of the License, or
13
#   (at your option) any later version.
14
#
15
#   This program is distributed in the hope that it will be useful,
16
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
#   GNU General Public License for more details.
19
#
20
#   You should have received a copy of the GNU General Public License
21
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
#
23
24
import re
25
import sys
161 by Jonathan Patrick Davies
* buildd:
26
import urllib2
27
from optparse import OptionGroup
28
from optparse import OptionParser
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
29
from urllib import urlencode
30
31
sys.path.append('/usr/share/ubuntu-dev-tools/')
32
import common
33
163 by Jonathan Patrick Davies
* buildd: Improve usage notes.
34
# Usage.
35
usage = "%prog <srcpackage> <release> <operation>\n\n"
36
usage += "Where operation may be one of: rescore, retry, or status.\n"
37
usage += "Only Launchpad Buildd Admins may rescore package builds."
38
161 by Jonathan Patrick Davies
* buildd:
39
# Prepare our option parser.
40
optParser = OptionParser(usage)
41
42
# Retry options 
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
43
retryRescoreOptions = OptionGroup(optParser, "Retry and rescore options",
44
    "These options may only be used with the 'retry' and 'rescore' operations.")
45
retryRescoreOptions.add_option("-a", "--arch", type = "string",
161 by Jonathan Patrick Davies
* buildd:
46
    action = "store", dest = "architecture",
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
47
    help = "Rebuild or rescore a specific architecture.")
161 by Jonathan Patrick Davies
* buildd:
48
49
# Add the retry options to the main group.
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
50
optParser.add_option_group(retryRescoreOptions)
161 by Jonathan Patrick Davies
* buildd:
51
52
# Parse our options.
53
(options, args) = optParser.parse_args()
54
55
# Check we have the correct number of arguments.
56
if len(args) < 3:
57
    optParser.error("Incorrect number of arguments.")
58
162 by Jonathan Patrick Davies
* buildd: Check that the architecture specified is correct and that --arch is
59
package = str(args[0]).lower()
60
release = str(args[1]).lower()
161 by Jonathan Patrick Davies
* buildd:
61
op      = str(args[2]).lower()
62
63
# Check our operation.
64
if op not in ("rescore", "retry", "status"):
65
    print >> sys.stderr, "Invalid operation: %s." % op
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
66
    sys.exit(1)
67
161 by Jonathan Patrick Davies
* buildd:
68
# If the user has specified an architecture to build, we only wish to rebuild it
69
# and nothing else.
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
70
if op not in ("retry", 'rescore') and options.architecture:
162 by Jonathan Patrick Davies
* buildd: Check that the architecture specified is correct and that --arch is
71
    print >> sys.stderr, "Operation %s does not use the --arch option." % op
72
    sys.exit(1)
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
73
elif op in ("retry", "rescore") and options.architecture:
168 by Jonathan Patrick Davies
* buildd:
74
    if options.architecture not in ("amd64", "hppa", "i386", "ia64", "lpia",
75
            "powerpc", "sparc"):
162 by Jonathan Patrick Davies
* buildd: Check that the architecture specified is correct and that --arch is
76
        print >> sys.stderr, "Invalid architecture specified: %s." % options.architecture
77
        sys.exit(1)
78
    else:
79
        oneArch = True
80
else:
81
    oneArch = False
161 by Jonathan Patrick Davies
* buildd:
82
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
83
# Prepare Launchpad cookie.
142 by Jonathan Patrick Davies
* requestsync: Use the functions in the common.py file above to authenticate
84
launchpadCookie = common.prepareLaunchpadCookie()
85
urlopener = common.setupLaunchpadUrlOpener(launchpadCookie)
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
86
87
# Find out the version in given release.
88
try:
89
	page = urlopener.open('https://launchpad.net/ubuntu/+source/' + package).read()
90
except urllib2.HTTPError:
161 by Jonathan Patrick Davies
* buildd:
91
    print >> sys.stderr, "The source package (%s) does not appear to exist " \
92
        "in Ubuntu." % package
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
93
    sys.exit(1)
94
161 by Jonathan Patrick Davies
* buildd:
95
m = re.search('"/ubuntu/%s/\+source/%s/(\d[^"]+)"' % (release,
96
    package.replace('+', '\+')), page)
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
97
if not m:
161 by Jonathan Patrick Davies
* buildd:
98
    print >> sys.stderr, "Cannot find this source package (%s) in this " \
99
        "release (%s)." % (package, release.capitalize())
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
100
    sys.exit(1)
161 by Jonathan Patrick Davies
* buildd:
101
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
102
version = m.group(1)
161 by Jonathan Patrick Davies
* buildd:
103
104
# Output details.
105
print "The source version for '%s' in %s is at %s." % (package,
106
    release.capitalize(), version)
107
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
108
# Parse out build URLs, states, and arches.
109
buildstats = {}
110
page = urlopener.open('https://launchpad.net/ubuntu/+source/%s/%s' % (package, version))
111
url = page.geturl()
112
page = page.read()
168 by Jonathan Patrick Davies
* buildd:
113
114
print "Current build status for this package is as follows:"
115
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
116
for m in re.finditer('"/ubuntu/\+source/%s/%s(/\+build/\d+)"[^\n]+\n\s*(\w+).*?<span>(\w+)</span>.*?</a>\s*([^\n]+)\n' %
117
    (package.replace('+', '\+'), version.replace('+', '\+')), page, re.S):
118
    if m.group(2) == release:
161 by Jonathan Patrick Davies
* buildd:
119
        print '%s: %s.' % (m.group(3), m.group(4))
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
120
        buildstats[url + m.group(1)] = [m.group(3).strip(), m.group(4).strip()]
121
122
# Operations.
123
if op == 'status':
124
    sys.exit(0)
125
126
for build, (arch, status) in buildstats.iteritems():
164 by Jonathan Patrick Davies
* buildd: Allow the rescoring of one arch too.
127
    if oneArch and not options.architecture == arch:
128
        # Skip this architecture.
129
        continue
130
168 by Jonathan Patrick Davies
* buildd:
131
    # Check if our package is successfully built and retry/rescore requested.
167 by Jonathan Patrick Davies
* buildd: Do not rescore or retry successfully built packages.
132
    if oneArch and options.architecture == arch:
133
        if status in ('Successfully built'):
134
            print "Package has been marked as successfully built on %s." % arch
135
            print "A %s of this package shall not be requested." % op
136
            sys.exit(0)
137
168 by Jonathan Patrick Davies
* buildd:
138
    # Check if package is building, before rescoring.
139
    if oneArch and options.architecture == arch:
140
        if op == "rescore" and status not in ("Needs building"):
141
            print "Package is not in the build queue on %s - shall not " \
142
                "rescore it." % arch
143
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
144
    if op == 'rescore':
145
        if status == 'Needs building':
161 by Jonathan Patrick Davies
* buildd:
146
            print 'Rescoring', build, '(%s).' % arch
147
            urlopener.open(build + '/+rescore', urlencode(
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
148
                {'SCORE': '5000', 'RESCORE': '1'}))
149
    elif op == 'retry':
150
        if status in ('Failed to build', 'Chroot problem', 'Failed to upload'):
161 by Jonathan Patrick Davies
* buildd:
151
            print 'Retrying:', build, '(%s).' % arch
152
            urlopener.open(build + '/+retry', urlencode(
139 by Jonathan Patrick Davies
* buildd: Imported from Martin Pitt's scripts at:
153
                {'RETRY': '1'}))