Merge lp:~gandelman-a/cloud-archive-utils/metabug into lp:cloud-archive-utils

Proposed by Adam Gandelman
Status: Work in progress
Proposed branch: lp:~gandelman-a/cloud-archive-utils/metabug
Merge into: lp:cloud-archive-utils
Diff against target: 322 lines (+211/-13)
4 files modified
bin/cloud-archive-metabug (+95/-0)
bin/cloud-archive-sru-released (+3/-1)
cloudarchive/common.py (+20/-0)
cloudarchive/utils.py (+93/-12)
To merge this branch: bzr merge lp:~gandelman-a/cloud-archive-utils/metabug
Reviewer Review Type Date Requested Status
Ubuntu Cloud Archive Team Pending
Review via email: mp+200362@code.launchpad.net

Description of the change

Adds a new utilitiy script: cloud-archive-metabug, which can be used to quickly open SRU tracking bugs ala Bug #1262788

Updates version constants for new Ubuntu/OS releases and adds some utility mappings.l

To post a comment you must log in.
18. By Adam Gandelman

Rebase on trunk, do not login to LP anonymously

Unmerged revisions

18. By Adam Gandelman

Rebase on trunk, do not login to LP anonymously

17. By Adam Gandelman

Adds cloud-archive-metabug script, updates existing version constants and adds a few more

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'bin/cloud-archive-metabug'
2--- bin/cloud-archive-metabug 1970-01-01 00:00:00 +0000
3+++ bin/cloud-archive-metabug 2014-01-03 00:54:05 +0000
4@@ -0,0 +1,95 @@
5+#!/usr/bin/python
6+
7+import optparse
8+import sys
9+
10+from ubuntutools.logger import Logger
11+
12+from cloudarchive import utils, common
13+
14+
15+MSG_TEMPLATE = """
16+This is a meta-bug used for tracking progress of the OpenStack
17+%(os_vers)s %(os_series)s stable updates to %(packages_list)s
18+in Ubuntu %(ubuntu_series)s %(ubuntu_vers)s and the Ubuntu Cloud Archive.
19+"""
20+
21+
22+def die(msg):
23+ Logger.error(msg)
24+ sys.exit(1)
25+
26+
27+def create_new_metabug(packages, os_vers):
28+ '''Creates a new meta bug report affecting a single package
29+ and populates with message'''
30+ p1 = packages[0]
31+ packages_list = ', '.join([p.capitalize() for p in packages])
32+ os_series = utils.openstack_series(os_vers)
33+ ubuntu_series = utils.ubuntu_series(os_series).capitalize()
34+ ubuntu_vers = utils.ubuntu_version(ubuntu_series)
35+ Logger.normal('Creating new bug report initially targetting %s' % p1)
36+ msg = MSG_TEMPLATE % locals()
37+ # TODO: Create and return the bug
38+
39+
40+if __name__ == '__main__':
41+ usage = 'usage: %prog [options] [projects]'
42+ parser = optparse.OptionParser(usage=usage)
43+ parser.add_option('-b', '--bug',
44+ help='Existing bug # to update',
45+ dest='bug_no', action='store')
46+ parser.add_option('-v', '--version',
47+ help='OpenStack Stable version (ie, 2013.1.2)',
48+ dest='os_version', action='store')
49+ (opts, args) = parser.parse_args()
50+
51+ if not opts.os_version:
52+ die('Must specify an OpenStack stable version')
53+ elif not args:
54+ die('Must specify a comma-separated list of packages to target')
55+
56+ packages = [a.strip() for a in args[0].split(',')]
57+ os_vers = opts.os_version
58+ os_series = utils.openstack_series(os_vers)
59+ ubuntu_series = utils.ubuntu_series(os_series)
60+
61+ Logger.normal(
62+ 'Meta-bug will target %s/%s affecting: %s' %
63+ (ubuntu_series, os_series, ' '.join(packages)))
64+
65+ if not opts.bug_no:
66+ bug = create_new_metabug(packages, os_vers)
67+ else:
68+ bug = utils.get_bug(opts.bug_no)
69+
70+ for p in packages:
71+ affects_package = False
72+ has_task = False
73+ found = False
74+
75+ for task in utils.affected_packages(bug):
76+ if task.name != p:
77+ found = False
78+ continue
79+
80+ # ensure metabug tasks are invalidated against ubuntu dev rel.
81+ if task.series == common.UBUNTU_DEV:
82+ if task.status != 'Invalid':
83+ utils.set_task_status(task.lp_task, status='Invalid')
84+ affects_package = True
85+
86+ if task.series == ubuntu_series:
87+ if task.status != 'Confirmed':
88+ utils.set_task_status(task.lp_task, status='Confirmed')
89+ has_task = True
90+
91+ if not affects_package:
92+ utils.create_task(
93+ bug=bug, package=p, series=common.UBUNTU_DEV, status='Invalid')
94+
95+ if not has_task:
96+ utils.create_task(
97+ bug=bug, package=p, series=ubuntu_series, status='Confirmed')
98+
99+ utils.set_cloud_archive_task_status(bug, 'Confirmed')
100
101=== modified file 'bin/cloud-archive-sru-released'
102--- bin/cloud-archive-sru-released 2013-07-01 20:47:20 +0000
103+++ bin/cloud-archive-sru-released 2014-01-03 00:54:05 +0000
104@@ -61,4 +61,6 @@
105 sys.exit(0)
106
107 utils.set_cloud_archive_task_status(lp_bug, status='Fix Released')
108- utils.post_message(bug=lp_bug, message=msg)
109+ utils.post_message(
110+ bug=lp_bug, message=msg,
111+ subject='Fix Released in the Ubuntu Cloud Archive')
112
113=== modified file 'cloudarchive/common.py'
114--- cloudarchive/common.py 2013-12-03 21:50:47 +0000
115+++ cloudarchive/common.py 2014-01-03 00:54:05 +0000
116@@ -22,6 +22,15 @@
117 "icehouse",
118 ]
119
120+
121+OS_VERSION = {
122+ "2012.2": "folsom",
123+ "2013.1": "grizzly",
124+ "2013.2": "havana",
125+ "2014.1": "icehouse",
126+}
127+
128+
129 SOURCE_RELEASE = {
130 "folsom": "quantal",
131 "grizzly": "raring",
132@@ -30,11 +39,22 @@
133 }
134
135 UBUNTU_SERIES = [
136+ 'precise',
137+ 'quantal',
138 'raring',
139 'saucy',
140 'trusty',
141 ]
142
143+
144+UBUNTU_VERSION = {
145+ '12.04': 'precise',
146+ '12.10': 'quantal',
147+ '13.04': 'raring',
148+ '13.10': 'saucy',
149+ '14.04': 'trust',
150+}
151+
152 UBUNTU_DEV = UBUNTU_SERIES[-1]
153 UBUNTU_STABLE = UBUNTU_SERIES[-2]
154
155
156=== modified file 'cloudarchive/utils.py'
157--- cloudarchive/utils.py 2013-12-03 19:49:46 +0000
158+++ cloudarchive/utils.py 2014-01-03 00:54:05 +0000
159@@ -1,18 +1,28 @@
160 import logging
161+import os
162 import re
163
164+from collections import namedtuple
165+
166 from apt_pkg import version_compare
167
168 from ubuntutools.logger import Logger
169-from common import SERIES, SOURCE_RELEASE, LTS_SERIES
170+from common import (
171+ SERIES, SOURCE_RELEASE, LTS_SERIES, OS_VERSION, UBUNTU_DEV, UBUNTU_VERSION)
172
173 from ubuntutools.lp.lpapicache import (Launchpad, Distribution,
174 PackageNotFoundException)
175
176+from lazr.restfulclient.errors import BadRequest
177+
178
179 def get_lp():
180+ if os.getenv('LP_STAGING'):
181+ service = 'staging'
182+ else:
183+ service = 'production'
184 if not Launchpad.logged_in:
185- Launchpad.login_anonymously()
186+ Launchpad.login(service=service)
187
188
189 def ubuntu_series(os_series):
190@@ -22,6 +32,17 @@
191 return SOURCE_RELEASE[r]
192
193
194+def ubuntu_version(ubuntu_series):
195+ '''Return the Ubuntu version number for a given series codename'''
196+ ubuntu_series = ubuntu_series.lower()
197+ for vers, codename in UBUNTU_VERSION.iteritems():
198+ if codename == ubuntu_series:
199+ return vers
200+ Logger.error(
201+ 'Could not determine Ubuntu version from series %s' % ubuntu_series)
202+ raise Exception
203+
204+
205 def lts_series(os_series):
206 '''Return the LTS cloud archive series for a given OpenStack Release'''
207 for u, o in LTS_SERIES.iteritems():
208@@ -29,6 +50,16 @@
209 return u
210
211
212+def openstack_series(os_version):
213+ '''Return OpenStack series name for a version string'''
214+ for vers, codename in OS_VERSION.iteritems():
215+ if os_version.startswith(vers):
216+ return codename
217+ Logger.error(
218+ 'Could not obtain OpenStack series for version: %s' % os_version)
219+ raise Exception
220+
221+
222 def query_ca_ppa(ppa='folsom-staging', owner='ubuntu-cloud-archive',
223 release=SERIES):
224 ''' Query a PPA for source packages and versions '''
225@@ -90,11 +121,58 @@
226
227 def affected_packages(bug):
228 '''Return a list of affected Ubuntu packages for given bug number'''
229- tgts = [task.target.name for task in bug.bug_tasks
230- if task.target.name != 'cloud-archive']
231+ bug_task = namedtuple('bug_task', 'name series status lp_task')
232+ tgts = []
233+ for task in bug.bug_tasks:
234+ tgt = task.target
235+ if (not hasattr(tgt, 'distribution') or
236+ tgt.distribution.name != 'ubuntu'):
237+ continue
238+ if not hasattr(tgt, 'distroseries'):
239+ # tasks affecting dev release have no distroseries
240+ tgts.append(
241+ bug_task(tgt.name, UBUNTU_DEV, task.status, task))
242+ else:
243+ tgts.append(
244+ bug_task(tgt.name, tgt.distroseries.name, task.status, task))
245 return list(set(tgts))
246
247
248+def set_task_status(task, status):
249+ Logger.normal(
250+ 'Setting status %s on %s' % (status, task.bug_target_display_name))
251+ task.status = status
252+ task.lp_save()
253+
254+
255+def create_task(bug, package, series=UBUNTU_DEV, status='Confirmed'):
256+ Logger.normal(
257+ 'Creating %s task affecting %s (%s) on (LP: %s).' %
258+ (status, package, series, bug.id))
259+ lp = get_lp()
260+ archive = lp.distributions['ubuntu']
261+ pkg = archive.getSourcePackage(name=package)
262+
263+ task = None
264+ try:
265+ task = bug.addTask(target=pkg)
266+ except BadRequest as e:
267+ if e.content.startswith('A fix for this bug has already been'):
268+ tsks = affected_packages(bug)
269+ for _package, _series, _status, _task in tsks:
270+ if _package == package and series == series:
271+ task = _task
272+ break
273+ else:
274+ raise e
275+
276+ if not task:
277+ Logger.error('Error adding task to bug')
278+ raise Exception
279+
280+ set_task_status(task, status)
281+
282+
283 def meta_bug_distribution(bug):
284 '''Return a list of Ubuntu releases a meta bug has been released to'''
285 bug_tasks = [bt for bt in bug.bug_tasks
286@@ -116,7 +194,7 @@
287 return sorted(rels).pop()
288
289
290-def post_message(bug, message):
291+def post_message(bug, message, subject=None):
292 '''Posts message to a bug'''
293 bug.newMessage(content=message,
294 subject='Fix Released in the Ubuntu Cloud Archive.')
295@@ -125,17 +203,20 @@
296
297 def set_cloud_archive_task_status(bug, status):
298 '''Sets status on a cloud archive bug task'''
299- bug_task = [bt for bt in bug.bug_tasks
300- if bt.bug_target_name == 'cloud-archive'].pop()
301+ tasks = [bt for bt in bug.bug_tasks
302+ if bt.bug_target_name == 'cloud-archive']
303
304- if not bug_task:
305- logging.error('Bug %s does not affect cloud archive, cant set status.')
306- raise Exception
307+ if tasks:
308+ bug_task = tasks.pop()
309+ else:
310+ lp = get_lp()
311+ ca = lp.projects['cloud-archive']
312+ bug_task = bug.addTask(target=ca)
313
314 bug_task.status = status
315 bug_task.lp_save()
316- logging.info('Status set on cloud-archive task (LP: #%s): %s.' %
317- (bug.id, status))
318+ Logger.normal('Status set on cloud-archive task (LP: #%s): %s.' %
319+ (bug.id, status))
320
321
322 def outdated_packages(os_release):

Subscribers

People subscribed via source and target branches