Merge lp:~brian-murray/ubuntu-archive-tools/sru-remove into lp:ubuntu-archive-tools

Proposed by Brian Murray on 2015-02-20
Status: Merged
Merged at revision: 936
Proposed branch: lp:~brian-murray/ubuntu-archive-tools/sru-remove
Merge into: lp:ubuntu-archive-tools
Diff against target: 253 lines (+183/-1)
2 files modified
sru-remove (+159/-0)
sru-report (+24/-1)
To merge this branch: bzr merge lp:~brian-murray/ubuntu-archive-tools/sru-remove
Reviewer Review Type Date Requested Status
Ubuntu Package Archive Administrators 2015-02-20 Pending
Review via email: mp+250492@code.launchpad.net

Description of the Change

This makes it easier to remove packages from -proposed that have failed to be verified in a timely fashion.

It includes a wrapper sru-remove that calls remove-package with a stock message, and updates the SRU bug reports by setting the task to "Won't Fix", removing the verification-needed and / or verification-needed-$series tags, unsubscribing ubuntu-sru and sru-verifcation, and commenting on the bug report. Here is an example of the work it did:

https://bugs.staging.launchpad.net/ubuntu/precise/+source/haproxy/+bug/1038139

It also includes a change to sru-report to include the packages that need to be removed due to a failure to verify e.g.:

sru-remove -s precise -p haproxy 1038139

Feel free to test it using these removable packages:

sru-remove -s precise -p charm-tools 1182905
sru-remove -s precise -p haproxy 1038139
sru-remove -s trusty -p haproxy 1038139
sru-remove -s trusty -p seabios 1366868

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'sru-remove'
2--- sru-remove 1970-01-01 00:00:00 +0000
3+++ sru-remove 2015-02-20 17:49:51 +0000
4@@ -0,0 +1,159 @@
5+#!/usr/bin/python
6+
7+# Copyright (C) 2015 Brian Murray <brian.murray@canonical.com>
8+
9+# This program is free software: you can redistribute it and/or modify
10+# it under the terms of the GNU General Public License as published by
11+# the Free Software Foundation; version 3 of the License.
12+#
13+# This program is distributed in the hope that it will be useful,
14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+# GNU General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License
19+# along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
21+'''Remove an SRU fom the -proposed pocket for a release.
22+
23+Remove a package from the -proposed pocket for a release of Ubuntu and comment
24+on bug reports regarding the removal of the package giving an explanation that
25+it was removed to due a failure for the SRU bug(s) to be verified in a timely
26+fashion.
27+
28+USAGE:
29+ sru-remove -s trusty -p homerun 12345
30+'''
31+
32+from __future__ import print_function
33+
34+import optparse
35+import re
36+import subprocess
37+import sys
38+
39+from launchpadlib.launchpad import Launchpad
40+
41+
42+def parse_options():
43+ '''Parse command line arguments.
44+
45+ Return (options, [bugs]) tuple.
46+ '''
47+
48+ parser = optparse.OptionParser(
49+ usage='Usage: %prog [options] source_package')
50+ parser.add_option(
51+ "-l", "--launchpad", dest="launchpad_instance", default="production")
52+ parser.add_option(
53+ "-s", dest="release", default=default_release, metavar="RELEASE",
54+ help="release (default: %s)" % default_release)
55+ parser.add_option(
56+ "-p", "--package", dest="sourcepkg")
57+
58+ opts, args = parser.parse_args()
59+
60+ return (opts, args)
61+
62+
63+def process_bug(launchpad, distroseries, sourcepkg, num):
64+ bug_target_re = re.compile(
65+ r'/ubuntu/(?:(?P<suite>[^/]+)/)?\+source/(?P<source>[^/]+)$')
66+ bug = launchpad.bugs[num]
67+ series_name = distroseries.name
68+ open_task = False
69+
70+ for task in bug.bug_tasks:
71+ # Ugly; we have to do URL-parsing to figure this out.
72+ # /ubuntu/+source/foo can be fed to launchpad.load() to get a
73+ # distribution_source_package, but /ubuntu/hardy/+source/foo can't.
74+ match = bug_target_re.search(task.target.self_link)
75+ if (not match or
76+ (sourcepkg and
77+ match.group('source') != sourcepkg)):
78+ print("Ignoring task %s in bug %s" % (task.web_link, num))
79+ continue
80+ if (match.group('suite') != series_name and
81+ match.group('suite') in supported_series and
82+ task.status == "Fix Committed"):
83+ open_task = True
84+ if (match.group('suite') == series_name and
85+ task.status == "Fix Committed"):
86+ task.status = "Won't Fix"
87+ task.lp_save()
88+ print("Success: task %s in bug %s" % (task.web_link, num))
89+ btags = bug.tags
90+ series_v_needed = 'verification-needed-%s' % series_name
91+ if series_v_needed in btags:
92+ # this dance is needed due to
93+ # https://bugs.launchpad.net/launchpadlib/+bug/254901
94+ tags = btags
95+ tags.remove(series_v_needed)
96+ bug.tags = tags
97+ bug.lp_save()
98+
99+ text = ('The version of %s in the proposed pocket of %s that was '
100+ 'purported to fix this bug report has been removed because '
101+ 'the bugs that were to be fixed by the upload were not '
102+ 'verified in a timely (105 days) fashion.' %
103+ (sourcepkg, series_name.title()))
104+ bug.newMessage(content=text,
105+ subject='Proposed package removed from archive')
106+
107+ # remove verification-needed tag if there are no open tasks
108+ if open_task:
109+ return
110+ # only unsubscribe the teams if there are no open tasks left
111+ bug.unsubscribe(person=launchpad.people['ubuntu-sru'])
112+ bug.unsubscribe(person=launchpad.people['sru-verification'])
113+ if 'verification-needed' in btags:
114+ # this dance is needed due to
115+ # https://bugs.launchpad.net/launchpadlib/+bug/254901
116+ tags = btags
117+ tags.remove('verification-needed')
118+ bug.tags = tags
119+ bug.lp_save()
120+
121+
122+if __name__ == '__main__':
123+
124+ default_release = 'utopic'
125+ removal_comment = ('The package was removed due to its SRU bug(s) '
126+ 'not being verified in a timely fashion.')
127+
128+ (opts, bugs) = parse_options()
129+
130+ launchpad = Launchpad.login_with('sru-remove', opts.launchpad_instance,
131+ version="devel")
132+ ubuntu = launchpad.distributions['ubuntu']
133+ # determine series for which we issue SRUs
134+ supported_series = []
135+ for serie in ubuntu.series:
136+ if serie.supported:
137+ supported_series.append(serie.name)
138+
139+ series = ubuntu.getSeries(name_or_version=opts.release)
140+ archive = ubuntu.main_archive
141+
142+ existing = [
143+ pkg for pkg in archive.getPublishedSources(
144+ exact_match=True, distro_series=series, pocket='Proposed',
145+ source_name=opts.sourcepkg, status='Published')]
146+
147+ if not existing:
148+ print("ERROR: %s was not found in -proposed for release %s." %
149+ (opts.sourcepkg, opts.release), file=sys.stderr)
150+ sys.exit(1)
151+
152+ rm_p_cmd = ["remove-package", "-m", removal_comment, "-y",
153+ "-l", opts.launchpad_instance, "-s",
154+ "%s-proposed" % opts.release, opts.sourcepkg]
155+ ret = subprocess.call(rm_p_cmd)
156+ if ret != 0:
157+ print("ERROR: There was an error removing %s from %s-proposed.\n"
158+ "The remove-package command returned %s." %
159+ (opts.sourcepkg, opts.release, ret), file=sys.stderr)
160+ sys.exit(1)
161+ # only comment on the bugs after removing the package
162+ for bug in bugs:
163+ process_bug(launchpad, series, opts.sourcepkg, bug)
164
165=== modified file 'sru-report'
166--- sru-report 2014-10-01 22:31:35 +0000
167+++ sru-report 2015-02-20 17:49:51 +0000
168@@ -210,6 +210,8 @@
169 pkgcleanup = []
170 pkgcleanup_release = []
171 pkgsuperseded = []
172+ # set of (series_name, srcpkg, [bugs])
173+ proposed_antique = []
174 for release in sorted(srus):
175 if not srus[release]:
176 continue
177@@ -263,6 +265,8 @@
178 print(' <td><a href="%s">%s</a></td> ' %
179 (lpurl + rpkg['proposed'], rpkg['proposed']))
180 print(' <td>')
181+ removable = True
182+ antique = False
183 for b, t in sorted(rpkg['bugs'].iteritems()):
184 cls = ' class="'
185 hover_text = ''
186@@ -275,11 +279,14 @@
187 'verification-done-%s' % release in t) and
188 'verification-needed' in t):
189 cls += ' verificationpartial'
190+ removable = False
191 elif ('verification-done' in t or
192 'verification-done-%s' % release in t):
193 cls += ' verified'
194+ removable = False
195 elif b in broken_bugs:
196 cls += ' broken'
197+ removable = False
198 else:
199 try:
200 bug = lp.bugs[b]
201@@ -299,6 +306,7 @@
202 if (m_date.replace(tzinfo=None) < today
203 - datetime.timedelta(16)):
204 cls += ' removal'
205+ antique = True
206 continue
207 hover_text = ''
208 if 'messages' in cls:
209@@ -316,6 +324,7 @@
210 'UTF-8') + ' - '
211 hover_text += m_owner.name.encode(
212 'UTF-8')
213+ antique = False
214 except ClientError as error:
215 # people who don't use lp anymore
216 if error == 'Gone':
217@@ -330,6 +339,9 @@
218 'title="%s" %s>#%d%s</a>' %
219 (b, hover_text.replace('"', ''), cls, b,
220 '(hw)' if 'hw-specific' in t else ''))
221+ if antique and removable:
222+ proposed_antique.append((releases[release].name, pkg,
223+ [str(b) for b in rpkg['bugs']]))
224 print('&nbsp;</td>')
225 print(' <td>%i</td></tr>' % age)
226 print('</table>')
227@@ -412,6 +424,17 @@
228 '-e %s %s' % (r, pkg[2]['proposed'], pkg[1]))
229 print('</pre>')
230
231+ print('<p>The following packages have not had their SRU bugs verified in '
232+ '105 days and should be removed from -proposed:</p>')
233+
234+ print('<pre>')
235+ for r in releases:
236+ for pkg in sorted(proposed_antique):
237+ if pkg[0].startswith(r):
238+ print('sru-remove -s %s -p %s %s' %
239+ (r, pkg[1], ' '.join(pkg[2])))
240+ print('</pre>')
241+
242 #
243 # kernel PPA packages
244 #
245@@ -639,7 +662,7 @@
246
247 kernels = defaultdict(dict)
248 for release in releases:
249- #if release != 'karmic': continue # for quick testing
250+ # if release != 'karmic': continue # for quick testing
251 for published in ppa.getPublishedSources(
252 status='Published', distro_series=releases[release]):
253 logging.debug(

Subscribers

People subscribed via source and target branches