Convert update_blueprint to use the Gerrit REST API
This calls the Gerrit REST API to retrieve subject and topic for a change instead of querying the Gerrit database. The ReviewDb was removed in Gerrit 3.0 [1], so we need to use the REST API instead. This also uses the Gerrit API to get the change commit message instead of running git commands directly in the git directory. [1] https://www.gerritcodereview.com/releases-readme.html#30-eol Change-Id: I25b67745d3943786767d6c8960ff19cdc51b5769
This commit is contained in:
parent
6b1c39df5d
commit
faca72ce59
|
@ -18,55 +18,28 @@
|
|||
# corresponding Launchpad blueprints with links back to the change.
|
||||
|
||||
import argparse
|
||||
import six
|
||||
from six.moves import configparser
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from launchpadlib import launchpad
|
||||
from launchpadlib import uris
|
||||
import pymysql
|
||||
import requests
|
||||
|
||||
from jeepyb import projects as p
|
||||
|
||||
|
||||
GERRIT_GIT_DIR = os.environ.get(
|
||||
'GERRIT_GIT_DIR', '/home/gerrit2/review_site/git')
|
||||
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_DEFAULT = '/home/gerrit2/review_site/etc/secure.config'
|
||||
GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
|
||||
GERRIT_SECURE_CONFIG_DEFAULT)
|
||||
GERRIT_API_URL = 'https://review.opendev.org'
|
||||
GERRIT_API_CHANGES_URL = GERRIT_API_URL + '/changes/'
|
||||
SPEC_RE = re.compile(r'\b(blueprint|bp)\b[ \t]*[#:]?[ \t]*(\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 = six.StringIO(text)
|
||||
c = configparser.ConfigParser(strict=False)
|
||||
c.readfp(fp)
|
||||
return c
|
||||
|
||||
|
||||
GERRIT_CONFIG = get_broken_config(GERRIT_CONFIG)
|
||||
SECURE_CONFIG = get_broken_config(GERRIT_SECURE_CONFIG)
|
||||
DB_HOST = GERRIT_CONFIG.get("database", "hostname")
|
||||
DB_USER = GERRIT_CONFIG.get("database", "username")
|
||||
DB_PASS = SECURE_CONFIG.get("database", "password")
|
||||
DB_DB = GERRIT_CONFIG.get("database", "database")
|
||||
LOG = logging.getLogger('update_blueprint')
|
||||
|
||||
|
||||
def update_spec(launchpad, project, name, subject, link, topic=None):
|
||||
|
@ -108,28 +81,55 @@ def update_spec(launchpad, project, name, subject, link, topic=None):
|
|||
spec.lp_save()
|
||||
|
||||
|
||||
def find_specs(launchpad, dbconn, args):
|
||||
git_dir_arg = '--git-dir={base_dir}/{project}.git'.format(
|
||||
base_dir=GERRIT_GIT_DIR,
|
||||
project=args.project)
|
||||
git_log = subprocess.Popen(
|
||||
[
|
||||
'git', git_dir_arg, 'log', '--no-merges',
|
||||
args.commit + '^1..' + args.commit
|
||||
],
|
||||
stdout=subprocess.PIPE).communicate()[0].decode('utf-8')
|
||||
|
||||
def find_specs(launchpad, args):
|
||||
# Newer gerrit provides the change argument in this format:
|
||||
# gtest-org%2Fgtest~master~I117f34aaa4253e0b82b98de9077f7188d55c3f33
|
||||
# So this should be unique to a branch and return a single change.
|
||||
change = args.change
|
||||
if '~' in change:
|
||||
# Newer gerrit provides the change argument in this format:
|
||||
# gtest-org%2Fgtest~master~I117f34aaa4253e0b82b98de9077f7188d55c3f33
|
||||
# So we need to split off the changeid if there is other data in there.
|
||||
change = change.rsplit('~', 1)[1]
|
||||
cur = dbconn.cursor()
|
||||
cur.execute("select subject, topic from changes where change_key=%s",
|
||||
change)
|
||||
subject, topic = cur.fetchone()
|
||||
specs = set([m.group(2) for m in SPEC_RE.finditer(git_log)])
|
||||
commit = args.commit
|
||||
|
||||
# Get the change to get the subject and topic.
|
||||
# Get Change: 'GET /changes/{change-id}'
|
||||
url = GERRIT_API_CHANGES_URL + change
|
||||
try:
|
||||
resp = requests.get(url, headers={'Accept': 'application/json'})
|
||||
except Exception:
|
||||
LOG.exception('Error calling: %s', url)
|
||||
return
|
||||
|
||||
if resp.status_code == 200:
|
||||
ret = json.loads(resp.text[4:])
|
||||
if not ret:
|
||||
return
|
||||
else:
|
||||
LOG.error('Request to %s returned: [%d] %s',
|
||||
resp.url, resp.status_code, resp.reason)
|
||||
return
|
||||
|
||||
subject = ret['subject']
|
||||
# topic is optional and update_spec() handles topic=None
|
||||
topic = ret.get('topic')
|
||||
|
||||
# Get the commit to get the commit message.
|
||||
# Get Commit: 'GET /changes/{change-id}/revisions/{revision-id}/commit'
|
||||
url = GERRIT_API_CHANGES_URL + change + '/revisions/' + commit + '/commit'
|
||||
try:
|
||||
resp = requests.get(url, headers={'Accept': 'application/json'})
|
||||
except Exception:
|
||||
LOG.exception('Error calling: %s', url)
|
||||
return
|
||||
|
||||
if resp.status_code == 200:
|
||||
ret = json.loads(resp.text[4:])
|
||||
if not ret:
|
||||
return
|
||||
else:
|
||||
LOG.error('Request to %s returned: [%d] %s',
|
||||
resp.url, resp.status_code, resp.reason)
|
||||
return
|
||||
|
||||
commit_message = ret['message']
|
||||
specs = set([m.group(2) for m in SPEC_RE.finditer(commit_message)])
|
||||
|
||||
if topic:
|
||||
topicspec = topic.split('/')[-1]
|
||||
|
@ -169,10 +169,7 @@ def main():
|
|||
'Gerrit User Sync', uris.LPNET_SERVICE_ROOT, GERRIT_CACHE_DIR,
|
||||
credentials_file=GERRIT_CREDENTIALS, version='devel')
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=DB_HOST, user=DB_USER, password=DB_PASS, db=DB_DB)
|
||||
|
||||
find_specs(lpconn, conn, args)
|
||||
find_specs(lpconn, args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in New Issue