248
by Martin Pitt
add sru-release |
1 |
#!/usr/bin/python
|
355
by Colin Watson
Apply GPLv3 to anything not already licensed; ok slangasek, broder, laney, kitterman, geser |
2 |
|
3 |
# Copyright (C) 2011, 2012 Canonical Ltd.
|
|
248
by Martin Pitt
add sru-release |
4 |
# Author: Martin Pitt <martin.pitt@canonical.com>
|
5 |
||
355
by Colin Watson
Apply GPLv3 to anything not already licensed; ok slangasek, broder, laney, kitterman, geser |
6 |
# This program is free software: you can redistribute it and/or modify
|
7 |
# it under the terms of the GNU General Public License as published by
|
|
8 |
# the Free Software Foundation; version 3 of the License.
|
|
9 |
#
|
|
10 |
# This program is distributed in the hope that it will be useful,
|
|
11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
# GNU General Public License for more details.
|
|
14 |
#
|
|
15 |
# You should have received a copy of the GNU General Public License
|
|
16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17 |
||
248
by Martin Pitt
add sru-release |
18 |
'''Release a proposed stable release update.
|
19 |
||
20 |
Copy packages from -proposed to -updates, and optionally to -security and the
|
|
21 |
development release.
|
|
22 |
||
23 |
USAGE:
|
|
24 |
sru-release [-s] [-d] <release> <package> [<package> ...]
|
|
25 |
'''
|
|
26 |
||
386
by Colin Watson
sru-release: add "from __future__ import print_function", needed for "print()" to work properly |
27 |
from __future__ import print_function |
28 |
||
555
by Colin Watson
Simplify using collections.defaultdict. |
29 |
from collections import defaultdict |
557
by Colin Watson
sru-release: reduce duplication using functools.partial |
30 |
from functools import partial |
351
by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate. |
31 |
import optparse |
248
by Martin Pitt
add sru-release |
32 |
import sys |
351
by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate. |
33 |
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
34 |
try: |
35 |
from urllib.request import urlopen |
|
36 |
except ImportError: |
|
37 |
from urllib import urlopen |
|
38 |
||
351
by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate. |
39 |
from launchpadlib.launchpad import Launchpad |
248
by Martin Pitt
add sru-release |
40 |
|
492
by Colin Watson
sort imports |
41 |
|
684
by Colin Watson
sru-release: add --exclude-bug option |
42 |
def match_srubugs(options, changesfileurl): |
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
43 |
'''match between bugs with verification- tag and bugs in changesfile'''
|
44 |
||
45 |
bugs = [] |
|
46 |
||
47 |
if changesfileurl is None: |
|
48 |
return bugs |
|
49 |
||
50 |
# Load changesfile
|
|
51 |
changelog = urlopen(changesfileurl) |
|
52 |
bugnums = [] |
|
53 |
for l in changelog: |
|
54 |
if l.startswith('Launchpad-Bugs-Fixed: '): |
|
55 |
bugnums = l.split()[1:] |
|
56 |
break
|
|
57 |
||
58 |
for b in bugnums: |
|
684
by Colin Watson
sru-release: add --exclude-bug option |
59 |
if b in options.exclude_bug: |
60 |
continue
|
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
61 |
try: |
62 |
bugs.append(launchpad.bugs[int(b)]) |
|
63 |
except: |
|
558
by Colin Watson
PEP-8 |
64 |
print('%s: bug %s does not exist or is not accessible' % |
65 |
(changesfileurl, b)) |
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
66 |
|
67 |
return bugs |
|
68 |
||
558
by Colin Watson
PEP-8 |
69 |
|
795.1.1
by Brian Murray
sru-release: add in package name when commenting on verified SRUs |
70 |
def update_sru_bug(bug, pkg): |
558
by Colin Watson
PEP-8 |
71 |
'''Unsubscribe SRU team and comment on bug re: how to report regressions'''
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
72 |
m_subjects = [m.subject for m in bug.messages] |
73 |
if 'Update Released' in m_subjects: |
|
773.1.1
by Brian Murray
sru-release: clarifying that is a comment that is not made not status / importance changes |
74 |
print('LP: #%s was not commented on' % bug.id) |
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
75 |
return
|
76 |
sru_team = launchpad.people['ubuntu-sru'] |
|
77 |
bug.unsubscribe(person=sru_team) |
|
795.1.1
by Brian Murray
sru-release: add in package name when commenting on verified SRUs |
78 |
text = ("The verification of the Stable Release Update for %s has " |
79 |
"completed successfully and the package has now been released "
|
|
80 |
"to -updates. Subsequently, the Ubuntu Stable Release Updates "
|
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
81 |
"Team is being unsubscribed and will not receive messages "
|
82 |
"about this bug report. In the event that you encounter "
|
|
83 |
"a regression using the package from -updates please report "
|
|
84 |
"a new bug using ubuntu-bug and tag the bug report "
|
|
839
by Colin Watson
typo |
85 |
"regression-update so we can easily find any regressions." % pkg) |
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
86 |
bug.newMessage(subject="Update Released", content=text) |
87 |
bug.lp_save() |
|
88 |
||
558
by Colin Watson
PEP-8 |
89 |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
90 |
def get_versions(options, sourcename): |
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
91 |
'''Get current package versions.
|
92 |
||
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
93 |
If options.pattern is True, return all versions for package names
|
94 |
matching options.pattern.
|
|
95 |
If options.pattern is False, only return one result.
|
|
274
by Colin Watson
remove trailing whitespace |
96 |
|
97 |
Return map pkgname -> {'release': version, 'updates': version,
|
|
98 |
'proposed': version, 'changesfile': url_of_proposed_changes,
|
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
99 |
'published': proposed_date}
|
248
by Martin Pitt
add sru-release |
100 |
'''
|
555
by Colin Watson
Simplify using collections.defaultdict. |
101 |
versions = defaultdict(dict) |
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
102 |
matches = archive.getPublishedSources( |
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
103 |
source_name=sourcename, exact_match=not options.pattern, |
104 |
status='Published', pocket='Proposed', distro_series=series) |
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
105 |
for match in matches: |
106 |
# versions in all pockets
|
|
545
by Colin Watson
Make all scripts pass pep8(1). |
107 |
for pub in archive.getPublishedSources( |
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
108 |
source_name=match.source_package_name, exact_match=True, |
109 |
status='Published', distro_series=series): |
|
555
by Colin Watson
Simplify using collections.defaultdict. |
110 |
versions[pub.source_package_name][pub.pocket.lower()] = ( |
111 |
pub.source_package_version) |
|
554
by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs |
112 |
if 'Proposed' in pub.pocket: |
558
by Colin Watson
PEP-8 |
113 |
versions[pub.source_package_name]['changesfile'] = ( |
114 |
pub.changesFileUrl()) |
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
115 |
# devel version
|
116 |
if devel_series: |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
117 |
for pub in archive.getPublishedSources( |
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
118 |
source_name=match.source_package_name, exact_match=True, |
119 |
status='Published', distro_series=devel_series): |
|
655
by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel> |
120 |
if pub.pocket in ('Release', 'Proposed'): |
121 |
versions[pub.source_package_name]['devel'] = ( |
|
122 |
pub.source_package_version) |
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
123 |
else: |
124 |
versions[match.source_package_name]['devel'] = None |
|
248
by Martin Pitt
add sru-release |
125 |
|
126 |
return versions |
|
127 |
||
545
by Colin Watson
Make all scripts pass pep8(1). |
128 |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
129 |
def release_package(options, package): |
248
by Martin Pitt
add sru-release |
130 |
'''Release a package.'''
|
131 |
||
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
132 |
pkg_versions_map = get_versions(options, package) |
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
133 |
if not pkg_versions_map: |
870
by Scott Kitterman
Inlude name of non-existing package when sru-release fails due to 'No such package ...'. |
134 |
message = 'ERROR: No such package, ' + package + ', in -proposed, aborting\n' |
135 |
sys.stderr.write(message) |
|
248
by Martin Pitt
add sru-release |
136 |
sys.exit(1) |
137 |
||
364
by Colin Watson
dict.keys/dict.items -> dict.iterkeys/dict.iteritems when used as an iterable |
138 |
for pkg, versions in pkg_versions_map.iteritems(): |
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
139 |
print('--- Releasing %s ---' % pkg) |
140 |
print('Proposed: %s' % versions['proposed']) |
|
141 |
if 'security' in versions: |
|
142 |
print('Security: %s' % versions['security']) |
|
143 |
if 'updates' in versions: |
|
144 |
print('Updates: %s' % versions['updates']) |
|
145 |
else: |
|
146 |
print('Release: %s' % versions.get('release')) |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
147 |
if options.devel and 'devel' in versions: |
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
148 |
print('Devel: %s' % versions['devel']) |
149 |
||
557
by Colin Watson
sru-release: reduce duplication using functools.partial |
150 |
copy = partial( |
151 |
archive.copyPackage, from_archive=archive, include_binaries=True, |
|
560
by Colin Watson
auto-sync, copy-proposed-kernel, sru-release: automatically approve copies |
152 |
source_name=pkg, version=versions['proposed'], auto_approve=True) |
557
by Colin Watson
sru-release: reduce duplication using functools.partial |
153 |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
154 |
if options.devel: |
545
by Colin Watson
Make all scripts pass pep8(1). |
155 |
if ('devel' not in versions or |
156 |
versions['devel'] in ( |
|
157 |
versions.get('updates', 'notexisting'), |
|
158 |
versions['release'])): |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
159 |
if not options.no_act: |
655
by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel> |
160 |
copy(to_pocket='Proposed', to_series=devel_series.name) |
545
by Colin Watson
Make all scripts pass pep8(1). |
161 |
print('Version in %s matches development series, ' |
655
by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel> |
162 |
'copied to %s-proposed' % (release, devel_series.name)) |
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
163 |
else: |
545
by Colin Watson
Make all scripts pass pep8(1). |
164 |
print('ERROR: Version in %s does not match development ' |
165 |
'series, not copying' % release) |
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
166 |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
167 |
if options.no_act: |
168 |
if options.release: |
|
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
169 |
print('Would copy to %s' % release) |
170 |
else: |
|
171 |
print('Would copy to %s-updates' % release) |
|
172 |
else: |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
173 |
if options.release: |
609
by Colin Watson
sru-release: fix comment |
174 |
# -proposed -> release
|
557
by Colin Watson
sru-release: reduce duplication using functools.partial |
175 |
copy(to_pocket='Release', to_series=release) |
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
176 |
print('Copied to %s' % release) |
177 |
else: |
|
178 |
# -proposed -> -updates
|
|
825
by Colin Watson
sru-release: update comment about which releases are phased |
179 |
# only phasing updates for >=raring to start
|
878
by Colin Watson
sru-release: drop support for quantal |
180 |
if (release not in ('lucid', 'precise') and |
776.1.2
by Brian Murray
sru-release: modify logic for release checking for setting p-u-p |
181 |
not options.security): |
764.1.1
by Brian Murray
sru-release: phased updates are being started with raring |
182 |
copy(to_pocket='Updates', to_series=release, |
833.1.1
by Brian Murray
sru-release: add an option to specify the phased_update_percentage |
183 |
phased_update_percentage=options.percentage) |
764.1.1
by Brian Murray
sru-release: phased updates are being started with raring |
184 |
else: |
185 |
copy(to_pocket='Updates', to_series=release) |
|
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
186 |
print('Copied to %s-updates' % release) |
836
by Adam Conrad
sru-release: Add --no-bugs option |
187 |
if not options.no_bugs: |
188 |
sru_bugs = match_srubugs(options, versions['changesfile']) |
|
189 |
for sru_bug in sru_bugs: |
|
190 |
if 'verification-needed' not in sru_bug.tags: |
|
191 |
update_sru_bug(sru_bug, pkg) |
|
258
by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-" |
192 |
|
193 |
# -proposed -> -security
|
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
194 |
if options.security: |
195 |
if options.no_act: |
|
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
196 |
print('Would copy to %s-security' % release) |
197 |
else: |
|
557
by Colin Watson
sru-release: reduce duplication using functools.partial |
198 |
copy(to_pocket='Security', to_series=release) |
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
199 |
print('Copied to %s-security' % release) |
248
by Martin Pitt
add sru-release |
200 |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
201 |
|
248
by Martin Pitt
add sru-release |
202 |
if __name__ == '__main__': |
545
by Colin Watson
Make all scripts pass pep8(1). |
203 |
parser = optparse.OptionParser( |
204 |
usage='usage: %prog [options] <release> <package> [<package> ...]') |
|
248
by Martin Pitt
add sru-release |
205 |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
206 |
parser.add_option( |
207 |
'-l', '--launchpad', dest='launchpad_instance', default='production') |
|
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
208 |
parser.add_option( |
731
by Colin Watson
sru-release: drop short option -s for --security; too easily confused with --suite/--series in other tools |
209 |
'--security', action='store_true', default=False, |
545
by Colin Watson
Make all scripts pass pep8(1). |
210 |
help='Additionally copy to -security pocket') |
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
211 |
parser.add_option( |
212 |
'-d', '--devel', action='store_true', default=False, |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
213 |
help='Additionally copy to development release (only works if that ' |
214 |
'has the same version as <release>)') |
|
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
215 |
parser.add_option( |
216 |
'-r', '--release', action='store_true', default=False, |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
217 |
help='Copy to release pocket instead of -updates (useful for staging ' |
218 |
'uploads in development release)') |
|
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
219 |
parser.add_option( |
833.1.1
by Brian Murray
sru-release: add an option to specify the phased_update_percentage |
220 |
"-z", "--percentage", type="int", default=10, |
221 |
metavar="PERCENTAGE", help="set phased update percentage") |
|
222 |
parser.add_option( |
|
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
223 |
'-n', '--no-act', action='store_true', default=False, |
545
by Colin Watson
Make all scripts pass pep8(1). |
224 |
help='Only perform checks, but do not actually copy packages') |
677
by Colin Watson
make all scripts pass current stricter pep8(1) in raring |
225 |
parser.add_option( |
226 |
'-p', '--pattern', action='store_true', default=False, |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
227 |
help='Treat package names as patterns, not exact matches') |
684
by Colin Watson
sru-release: add --exclude-bug option |
228 |
parser.add_option( |
836
by Adam Conrad
sru-release: Add --no-bugs option |
229 |
'--no-bugs', action='store_true', default=False, |
230 |
help='Do not act on any bugs (helpful to avoid races).') |
|
231 |
parser.add_option( |
|
684
by Colin Watson
sru-release: add --exclude-bug option |
232 |
'--exclude-bug', action='append', default=[], metavar='BUG', |
233 |
help='Do not update BUG.') |
|
248
by Martin Pitt
add sru-release |
234 |
|
235 |
options, args = parser.parse_args() |
|
236 |
||
237 |
if len(args) < 2: |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
238 |
parser.error( |
239 |
'You must specify a release and source package(s), see --help') |
|
248
by Martin Pitt
add sru-release |
240 |
|
390
by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release |
241 |
if options.release and (options.security or options.devel): |
242 |
parser.error('-r and -s/-d are mutually exclusive, see --help') |
|
243 |
||
248
by Martin Pitt
add sru-release |
244 |
release = args.pop(0) |
245 |
packages = args |
|
246 |
||
372
by Colin Watson
sru-release: use Archive.copyPackage (asynchronous) rather than Archive.syncSource (synchronous), which should avoid timeouts |
247 |
launchpad = Launchpad.login_with( |
395
by Colin Watson
sru-release: add -l/--launchpad option |
248 |
'ubuntu-archive-tools', options.launchpad_instance, version='devel') |
248
by Martin Pitt
add sru-release |
249 |
ubuntu = launchpad.distributions['ubuntu'] |
250 |
series = ubuntu.getSeries(name_or_version=release) |
|
408
by Martin Pitt
sru-release: use ubuntu.current_series instead of ubuntu.getDevelopmentSeries(), as that also covers frozen releases |
251 |
devel_series = ubuntu.current_series |
252 |
if not devel_series: |
|
545
by Colin Watson
Make all scripts pass pep8(1). |
253 |
sys.stderr.write( |
254 |
'WARNING: No current development series, -d will not work\n') |
|
248
by Martin Pitt
add sru-release |
255 |
devel_series = None |
256 |
archive = ubuntu.getArchive(name='primary') |
|
257 |
||
258 |
for package in packages: |
|
683
by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it |
259 |
release_package(options, package) |