Add blueprint update script.
This script can be run from a gerrit hook to update Launchpad blueprints related to a given change. It looks for items like "bp foo", "blueprint foo", "bp: foo", "blueprint: foo", etc, and updates the foo blueprint of the current project to add a whiteboard note that links back to the change. It will also similarly update a blueprint if the topic of the change (after any initial text up to the first '/') is the name of a blueprint. This has a corresponding puppet configuration change to put it into production. Change-Id: I62f965ca7f14f589e3b299ea46729efb68abd06f Reviewed-on: https://review.openstack.org/253 Reviewed-by: Monty Taylor <mordred@inaugust.com> Tested-by: Jenkins
This commit is contained in:
124
gerrit/update_blueprint.py
Executable file
124
gerrit/update_blueprint.py
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is designed to be called by a gerrit hook. It searched new
|
||||
# patchsets for strings like "blueprint FOO" or "bp FOO" and updates
|
||||
# corresponding Launchpad blueprints with links back to the change.
|
||||
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
from launchpadlib.uris import LPNET_SERVICE_ROOT
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import StringIO
|
||||
import ConfigParser
|
||||
import MySQLdb
|
||||
|
||||
BASE_DIR = '/home/gerrit2/review_site'
|
||||
GERRIT_CACHE_DIR = os.path.expanduser(os.environ.get('GERRIT_CACHE_DIR',
|
||||
'~/.launchpadlib/cache'))
|
||||
GERRIT_CREDENTIALS = os.path.expanduser(os.environ.get('GERRIT_CREDENTIALS',
|
||||
'~/.launchpadlib/creds'))
|
||||
GERRIT_CONFIG = os.environ.get('GERRIT_CONFIG',
|
||||
'/home/gerrit2/review_site/etc/gerrit.config')
|
||||
GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
|
||||
'/home/gerrit2/review_site/etc/secure.config')
|
||||
SPEC_RE = re.compile(r'(blueprint|bp)\s*[#:]?\s*(\S+)', re.I)
|
||||
BODY_RE = re.compile(r'^\s+.*$')
|
||||
|
||||
def get_broken_config(filename):
|
||||
""" gerrit config ini files are broken and have leading tabs """
|
||||
text = ""
|
||||
with open(filename,"r") as conf:
|
||||
for line in conf.readlines():
|
||||
text = "%s%s" % (text, line.lstrip())
|
||||
|
||||
fp = StringIO.StringIO(text)
|
||||
c=ConfigParser.ConfigParser()
|
||||
c.readfp(fp)
|
||||
return c
|
||||
|
||||
GERRIT_CONFIG = get_broken_config(GERRIT_CONFIG)
|
||||
SECURE_CONFIG = get_broken_config(GERRIT_SECURE_CONFIG)
|
||||
DB_USER = GERRIT_CONFIG.get("database", "username")
|
||||
DB_PASS = SECURE_CONFIG.get("database","password")
|
||||
DB_DB = GERRIT_CONFIG.get("database","database")
|
||||
|
||||
def update_spec(launchpad, project, name, subject, link):
|
||||
# For testing, if a project doesn't match openstack/foo, use
|
||||
# the openstack-ci project instead.
|
||||
group, project = project.split('/')
|
||||
if group != 'openstack':
|
||||
project = 'openstack-ci'
|
||||
|
||||
spec = launchpad.projects[project].getSpecification(name=name)
|
||||
if not spec: return
|
||||
|
||||
wb = spec.whiteboard.strip()
|
||||
if link not in wb:
|
||||
wb += "\n\n\nAddressed by %(link)s\n %(subject)s\n" % dict(subject=subject,
|
||||
link=link)
|
||||
spec.whiteboard = wb
|
||||
spec.lp_save()
|
||||
|
||||
def find_specs(launchpad, dbconn, args):
|
||||
git_log = subprocess.Popen(['git',
|
||||
'--git-dir=' + BASE_DIR + '/git/' + args.project + '.git',
|
||||
'log', '--no-merges',
|
||||
args.commit + '^1..' + args.commit],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
|
||||
cur = dbconn.cursor()
|
||||
cur.execute("select subject, topic from changes where change_key=%s", args.change)
|
||||
subject, topic = cur.fetchone()
|
||||
specs = set([m.group(2) for m in SPEC_RE.finditer(git_log)])
|
||||
|
||||
if topic:
|
||||
topic = topic.split('/')[-1]
|
||||
specs |= set([topic])
|
||||
|
||||
for spec in specs:
|
||||
update_spec(launchpad, args.project, spec, subject, args.change_url)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('hook')
|
||||
#common
|
||||
parser.add_argument('--change', default=None)
|
||||
parser.add_argument('--change-url', default=None)
|
||||
parser.add_argument('--project', default=None)
|
||||
parser.add_argument('--branch', default=None)
|
||||
parser.add_argument('--commit', default=None)
|
||||
#change-merged
|
||||
parser.add_argument('--submitter', default=None)
|
||||
# patchset-created
|
||||
parser.add_argument('--uploader', default=None)
|
||||
parser.add_argument('--patchset', default=None)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
launchpad = Launchpad.login_with('Gerrit User Sync', LPNET_SERVICE_ROOT,
|
||||
GERRIT_CACHE_DIR,
|
||||
credentials_file = GERRIT_CREDENTIALS,
|
||||
version='devel')
|
||||
|
||||
conn = MySQLdb.connect(user = DB_USER, passwd = DB_PASS, db = DB_DB)
|
||||
|
||||
find_specs(launchpad, conn, args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user