
Jenkins went away, and Zuul soon would stop pretending to be Jenkins [1]. Support new user name along with the old one. [1] http://lists.openstack.org/pipermail/openstack-dev/2016-June/097595.html Change-Id: I81ce306af044c3a2e76ff8a7685bcfe964292f0b
148 lines
4.9 KiB
Python
148 lines
4.9 KiB
Python
# Copyright (c) 2015 Tintri. All rights reserved.
|
|
#
|
|
# 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.
|
|
|
|
from datetime import datetime
|
|
import json
|
|
import re
|
|
|
|
from ciwatch.config import Config
|
|
from ciwatch import db
|
|
from ciwatch.log import logger
|
|
from ciwatch import models
|
|
from zuul.lib.gerrit import Gerrit
|
|
|
|
pipeline_pattern = re.compile("\((.*)\spipeline\)")
|
|
|
|
possible_results = "FAILURE|SUCCESS|NOT_REGISTERED|UNSTABLE"
|
|
comment_pattern = re.compile("[-*]\s+([^\s*]+)\s+(http[^\s*]+) : (%s)" %
|
|
possible_results)
|
|
trusted_author_names = ["Jenkins check", "Zuul check"]
|
|
|
|
|
|
def _process_project_name(project_name):
|
|
return project_name.split('/')[-1]
|
|
|
|
|
|
def extract_pipeline_name(line):
|
|
match = pipeline_pattern.search(line)
|
|
if match is not None:
|
|
return match.group(1)
|
|
|
|
|
|
def _process_event(event):
|
|
comment = event['comment']
|
|
# Find all the CIs voting in this comment
|
|
lines = comment.splitlines()
|
|
event['ci-status'] = {}
|
|
pipeline = extract_pipeline_name(lines[2])
|
|
if pipeline is not None:
|
|
event["author"]["name"] = event["author"]["name"] + ' ' + pipeline
|
|
for line in lines:
|
|
match = comment_pattern.search(line)
|
|
if match is not None:
|
|
ci_name = match.group(1)
|
|
log_url = match.group(2)
|
|
result = match.group(3)
|
|
event['ci-status'][ci_name] = {
|
|
"result": result,
|
|
"log_url": log_url}
|
|
|
|
|
|
def _is_ci_user(name):
|
|
ci_keywords = ['CI', 'Jenkins', 'Bot', 'Zuul']
|
|
return any(word in name for word in ci_keywords)
|
|
|
|
|
|
# Check if this is a third party CI event
|
|
def _is_valid(event, projects):
|
|
if (event.get('type', 'nill') == 'comment-added' and
|
|
_is_ci_user(event['author'].get('name', '')) and
|
|
_process_project_name(
|
|
event['change']['project']) in projects and
|
|
event['change']['branch'] == 'master'):
|
|
return True
|
|
return False
|
|
|
|
|
|
def _store_event(event, datadir):
|
|
with open(datadir + '/third-party-ci.log', 'a') as f:
|
|
json.dump(event, f)
|
|
f.write('\n')
|
|
add_event_to_db(event)
|
|
return event
|
|
|
|
|
|
def parse_event(event, projects):
|
|
if _is_valid(event, projects):
|
|
_process_event(event)
|
|
logger.info('Parsed valid event: %s', event)
|
|
return event
|
|
return None
|
|
|
|
|
|
def add_event_to_db(event, commit_=True):
|
|
project = db.get_project(_process_project_name(
|
|
event["change"]["project"]))
|
|
patch_set = db.get_or_create(
|
|
models.PatchSet,
|
|
commit_=False,
|
|
project_id=project.id,
|
|
ref=event['patchSet']['ref'],
|
|
commit_message=event['change']['commitMessage'],
|
|
created=datetime.fromtimestamp(
|
|
int(event['patchSet']['createdOn'])))
|
|
trusted = (event["author"]["name"] in trusted_author_names)
|
|
|
|
if trusted and "approvals" in event:
|
|
if event["approvals"][0]["value"] in ("1", "2"):
|
|
patch_set.verified = True
|
|
elif event["approvals"][0]["value"] in ("-1", "-2"):
|
|
patch_set.verified = False
|
|
|
|
owner_name = event["author"]["name"]
|
|
owner = db.get_or_create(models.CiOwner, name=owner_name)
|
|
for ci, data in event['ci-status'].iteritems():
|
|
ci_server = db.get_or_create(models.CiServer,
|
|
commit_=False,
|
|
name=ci,
|
|
trusted=trusted,
|
|
ci_owner_id=owner.id)
|
|
db.update_or_create_comment(commit_=False,
|
|
result=data["result"],
|
|
log_url=data["log_url"],
|
|
ci_server_id=ci_server.id,
|
|
patch_set_id=patch_set.id)
|
|
if commit_:
|
|
db.Session().commit()
|
|
|
|
|
|
def main():
|
|
config = Config()
|
|
db.create_projects() # This will make sure the database has projects in it
|
|
gerrit = Gerrit(
|
|
hostname=config.cfg.AccountInfo.gerrit_host,
|
|
username=config.cfg.AccountInfo.gerrit_username,
|
|
port=int(config.cfg.AccountInfo.gerrit_port),
|
|
keyfile=config.cfg.AccountInfo.gerrit_ssh_key
|
|
)
|
|
gerrit.startWatching()
|
|
while True:
|
|
event = gerrit.getEvent()[1]
|
|
parsed_event = parse_event(event, config.get_projects())
|
|
if parsed_event is not None:
|
|
_store_event(parsed_event, config.DATA_DIR)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|