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
=== added file 'bin/cloud-archive-metabug'
--- bin/cloud-archive-metabug 1970-01-01 00:00:00 +0000
+++ bin/cloud-archive-metabug 2014-01-03 00:54:05 +0000
@@ -0,0 +1,95 @@
1#!/usr/bin/python
2
3import optparse
4import sys
5
6from ubuntutools.logger import Logger
7
8from cloudarchive import utils, common
9
10
11MSG_TEMPLATE = """
12This is a meta-bug used for tracking progress of the OpenStack
13%(os_vers)s %(os_series)s stable updates to %(packages_list)s
14in Ubuntu %(ubuntu_series)s %(ubuntu_vers)s and the Ubuntu Cloud Archive.
15"""
16
17
18def die(msg):
19 Logger.error(msg)
20 sys.exit(1)
21
22
23def create_new_metabug(packages, os_vers):
24 '''Creates a new meta bug report affecting a single package
25 and populates with message'''
26 p1 = packages[0]
27 packages_list = ', '.join([p.capitalize() for p in packages])
28 os_series = utils.openstack_series(os_vers)
29 ubuntu_series = utils.ubuntu_series(os_series).capitalize()
30 ubuntu_vers = utils.ubuntu_version(ubuntu_series)
31 Logger.normal('Creating new bug report initially targetting %s' % p1)
32 msg = MSG_TEMPLATE % locals()
33 # TODO: Create and return the bug
34
35
36if __name__ == '__main__':
37 usage = 'usage: %prog [options] [projects]'
38 parser = optparse.OptionParser(usage=usage)
39 parser.add_option('-b', '--bug',
40 help='Existing bug # to update',
41 dest='bug_no', action='store')
42 parser.add_option('-v', '--version',
43 help='OpenStack Stable version (ie, 2013.1.2)',
44 dest='os_version', action='store')
45 (opts, args) = parser.parse_args()
46
47 if not opts.os_version:
48 die('Must specify an OpenStack stable version')
49 elif not args:
50 die('Must specify a comma-separated list of packages to target')
51
52 packages = [a.strip() for a in args[0].split(',')]
53 os_vers = opts.os_version
54 os_series = utils.openstack_series(os_vers)
55 ubuntu_series = utils.ubuntu_series(os_series)
56
57 Logger.normal(
58 'Meta-bug will target %s/%s affecting: %s' %
59 (ubuntu_series, os_series, ' '.join(packages)))
60
61 if not opts.bug_no:
62 bug = create_new_metabug(packages, os_vers)
63 else:
64 bug = utils.get_bug(opts.bug_no)
65
66 for p in packages:
67 affects_package = False
68 has_task = False
69 found = False
70
71 for task in utils.affected_packages(bug):
72 if task.name != p:
73 found = False
74 continue
75
76 # ensure metabug tasks are invalidated against ubuntu dev rel.
77 if task.series == common.UBUNTU_DEV:
78 if task.status != 'Invalid':
79 utils.set_task_status(task.lp_task, status='Invalid')
80 affects_package = True
81
82 if task.series == ubuntu_series:
83 if task.status != 'Confirmed':
84 utils.set_task_status(task.lp_task, status='Confirmed')
85 has_task = True
86
87 if not affects_package:
88 utils.create_task(
89 bug=bug, package=p, series=common.UBUNTU_DEV, status='Invalid')
90
91 if not has_task:
92 utils.create_task(
93 bug=bug, package=p, series=ubuntu_series, status='Confirmed')
94
95 utils.set_cloud_archive_task_status(bug, 'Confirmed')
096
=== modified file 'bin/cloud-archive-sru-released'
--- bin/cloud-archive-sru-released 2013-07-01 20:47:20 +0000
+++ bin/cloud-archive-sru-released 2014-01-03 00:54:05 +0000
@@ -61,4 +61,6 @@
61 sys.exit(0)61 sys.exit(0)
6262
63 utils.set_cloud_archive_task_status(lp_bug, status='Fix Released')63 utils.set_cloud_archive_task_status(lp_bug, status='Fix Released')
64 utils.post_message(bug=lp_bug, message=msg)64 utils.post_message(
65 bug=lp_bug, message=msg,
66 subject='Fix Released in the Ubuntu Cloud Archive')
6567
=== modified file 'cloudarchive/common.py'
--- cloudarchive/common.py 2013-12-03 21:50:47 +0000
+++ cloudarchive/common.py 2014-01-03 00:54:05 +0000
@@ -22,6 +22,15 @@
22 "icehouse",22 "icehouse",
23]23]
2424
25
26OS_VERSION = {
27 "2012.2": "folsom",
28 "2013.1": "grizzly",
29 "2013.2": "havana",
30 "2014.1": "icehouse",
31}
32
33
25SOURCE_RELEASE = {34SOURCE_RELEASE = {
26 "folsom": "quantal",35 "folsom": "quantal",
27 "grizzly": "raring",36 "grizzly": "raring",
@@ -30,11 +39,22 @@
30}39}
3140
32UBUNTU_SERIES = [41UBUNTU_SERIES = [
42 'precise',
43 'quantal',
33 'raring',44 'raring',
34 'saucy',45 'saucy',
35 'trusty',46 'trusty',
36]47]
3748
49
50UBUNTU_VERSION = {
51 '12.04': 'precise',
52 '12.10': 'quantal',
53 '13.04': 'raring',
54 '13.10': 'saucy',
55 '14.04': 'trust',
56}
57
38UBUNTU_DEV = UBUNTU_SERIES[-1]58UBUNTU_DEV = UBUNTU_SERIES[-1]
39UBUNTU_STABLE = UBUNTU_SERIES[-2]59UBUNTU_STABLE = UBUNTU_SERIES[-2]
4060
4161
=== modified file 'cloudarchive/utils.py'
--- cloudarchive/utils.py 2013-12-03 19:49:46 +0000
+++ cloudarchive/utils.py 2014-01-03 00:54:05 +0000
@@ -1,18 +1,28 @@
1import logging1import logging
2import os
2import re3import re
34
5from collections import namedtuple
6
4from apt_pkg import version_compare7from apt_pkg import version_compare
58
6from ubuntutools.logger import Logger9from ubuntutools.logger import Logger
7from common import SERIES, SOURCE_RELEASE, LTS_SERIES10from common import (
11 SERIES, SOURCE_RELEASE, LTS_SERIES, OS_VERSION, UBUNTU_DEV, UBUNTU_VERSION)
812
9from ubuntutools.lp.lpapicache import (Launchpad, Distribution,13from ubuntutools.lp.lpapicache import (Launchpad, Distribution,
10 PackageNotFoundException)14 PackageNotFoundException)
1115
16from lazr.restfulclient.errors import BadRequest
17
1218
13def get_lp():19def get_lp():
20 if os.getenv('LP_STAGING'):
21 service = 'staging'
22 else:
23 service = 'production'
14 if not Launchpad.logged_in:24 if not Launchpad.logged_in:
15 Launchpad.login_anonymously()25 Launchpad.login(service=service)
1626
1727
18def ubuntu_series(os_series):28def ubuntu_series(os_series):
@@ -22,6 +32,17 @@
22 return SOURCE_RELEASE[r]32 return SOURCE_RELEASE[r]
2333
2434
35def ubuntu_version(ubuntu_series):
36 '''Return the Ubuntu version number for a given series codename'''
37 ubuntu_series = ubuntu_series.lower()
38 for vers, codename in UBUNTU_VERSION.iteritems():
39 if codename == ubuntu_series:
40 return vers
41 Logger.error(
42 'Could not determine Ubuntu version from series %s' % ubuntu_series)
43 raise Exception
44
45
25def lts_series(os_series):46def lts_series(os_series):
26 '''Return the LTS cloud archive series for a given OpenStack Release'''47 '''Return the LTS cloud archive series for a given OpenStack Release'''
27 for u, o in LTS_SERIES.iteritems():48 for u, o in LTS_SERIES.iteritems():
@@ -29,6 +50,16 @@
29 return u50 return u
3051
3152
53def openstack_series(os_version):
54 '''Return OpenStack series name for a version string'''
55 for vers, codename in OS_VERSION.iteritems():
56 if os_version.startswith(vers):
57 return codename
58 Logger.error(
59 'Could not obtain OpenStack series for version: %s' % os_version)
60 raise Exception
61
62
32def query_ca_ppa(ppa='folsom-staging', owner='ubuntu-cloud-archive',63def query_ca_ppa(ppa='folsom-staging', owner='ubuntu-cloud-archive',
33 release=SERIES):64 release=SERIES):
34 ''' Query a PPA for source packages and versions '''65 ''' Query a PPA for source packages and versions '''
@@ -90,11 +121,58 @@
90121
91def affected_packages(bug):122def affected_packages(bug):
92 '''Return a list of affected Ubuntu packages for given bug number'''123 '''Return a list of affected Ubuntu packages for given bug number'''
93 tgts = [task.target.name for task in bug.bug_tasks124 bug_task = namedtuple('bug_task', 'name series status lp_task')
94 if task.target.name != 'cloud-archive']125 tgts = []
126 for task in bug.bug_tasks:
127 tgt = task.target
128 if (not hasattr(tgt, 'distribution') or
129 tgt.distribution.name != 'ubuntu'):
130 continue
131 if not hasattr(tgt, 'distroseries'):
132 # tasks affecting dev release have no distroseries
133 tgts.append(
134 bug_task(tgt.name, UBUNTU_DEV, task.status, task))
135 else:
136 tgts.append(
137 bug_task(tgt.name, tgt.distroseries.name, task.status, task))
95 return list(set(tgts))138 return list(set(tgts))
96139
97140
141def set_task_status(task, status):
142 Logger.normal(
143 'Setting status %s on %s' % (status, task.bug_target_display_name))
144 task.status = status
145 task.lp_save()
146
147
148def create_task(bug, package, series=UBUNTU_DEV, status='Confirmed'):
149 Logger.normal(
150 'Creating %s task affecting %s (%s) on (LP: %s).' %
151 (status, package, series, bug.id))
152 lp = get_lp()
153 archive = lp.distributions['ubuntu']
154 pkg = archive.getSourcePackage(name=package)
155
156 task = None
157 try:
158 task = bug.addTask(target=pkg)
159 except BadRequest as e:
160 if e.content.startswith('A fix for this bug has already been'):
161 tsks = affected_packages(bug)
162 for _package, _series, _status, _task in tsks:
163 if _package == package and series == series:
164 task = _task
165 break
166 else:
167 raise e
168
169 if not task:
170 Logger.error('Error adding task to bug')
171 raise Exception
172
173 set_task_status(task, status)
174
175
98def meta_bug_distribution(bug):176def meta_bug_distribution(bug):
99 '''Return a list of Ubuntu releases a meta bug has been released to'''177 '''Return a list of Ubuntu releases a meta bug has been released to'''
100 bug_tasks = [bt for bt in bug.bug_tasks178 bug_tasks = [bt for bt in bug.bug_tasks
@@ -116,7 +194,7 @@
116 return sorted(rels).pop()194 return sorted(rels).pop()
117195
118196
119def post_message(bug, message):197def post_message(bug, message, subject=None):
120 '''Posts message to a bug'''198 '''Posts message to a bug'''
121 bug.newMessage(content=message,199 bug.newMessage(content=message,
122 subject='Fix Released in the Ubuntu Cloud Archive.')200 subject='Fix Released in the Ubuntu Cloud Archive.')
@@ -125,17 +203,20 @@
125203
126def set_cloud_archive_task_status(bug, status):204def set_cloud_archive_task_status(bug, status):
127 '''Sets status on a cloud archive bug task'''205 '''Sets status on a cloud archive bug task'''
128 bug_task = [bt for bt in bug.bug_tasks206 tasks = [bt for bt in bug.bug_tasks
129 if bt.bug_target_name == 'cloud-archive'].pop()207 if bt.bug_target_name == 'cloud-archive']
130208
131 if not bug_task:209 if tasks:
132 logging.error('Bug %s does not affect cloud archive, cant set status.')210 bug_task = tasks.pop()
133 raise Exception211 else:
212 lp = get_lp()
213 ca = lp.projects['cloud-archive']
214 bug_task = bug.addTask(target=ca)
134215
135 bug_task.status = status216 bug_task.status = status
136 bug_task.lp_save()217 bug_task.lp_save()
137 logging.info('Status set on cloud-archive task (LP: #%s): %s.' %218 Logger.normal('Status set on cloud-archive task (LP: #%s): %s.' %
138 (bug.id, status))219 (bug.id, status))
139220
140221
141def outdated_packages(os_release):222def outdated_packages(os_release):

Subscribers

People subscribed via source and target branches