status: provide initial implementation for checking bot status.
This commit is contained in:
parent
b84beb6958
commit
704fc50dca
136
status.py
Executable file
136
status.py
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from osc import conf
|
||||
from osc.core import ET
|
||||
from osc.core import search
|
||||
from osc.core import xpath_join
|
||||
from osclib.comments import CommentAPI
|
||||
from osclib.core import request_age
|
||||
from osclib.memoize import memoize
|
||||
import sys
|
||||
|
||||
def print_debug(message):
|
||||
if conf.config['debug']:
|
||||
print(message)
|
||||
|
||||
def request_debug(request, age, threshold):
|
||||
print_debug('{}: {} {} [{}]'.format(request.get('id'), age, threshold, age <= threshold))
|
||||
|
||||
@memoize(session=True)
|
||||
def check_comment(apiurl, bot, **kwargs):
|
||||
if not len(kwargs):
|
||||
return False
|
||||
|
||||
api = CommentAPI(apiurl)
|
||||
comments = api.get_comments(**kwargs)
|
||||
comment = api.comment_find(comments, bot)[0]
|
||||
if comment:
|
||||
return (datetime.utcnow() - comment['when']).total_seconds()
|
||||
|
||||
return False
|
||||
|
||||
def check(apiurl, entity, entity_type='group', comment=False, bot=None,
|
||||
threshold=2 * 3600, threshold_require=True):
|
||||
queries = {'request': {'limit': 1000, 'withfullhistory': 1}}
|
||||
xpath = 'state[@name="new"] or state[@name="review"]'
|
||||
|
||||
if entity == 'staging-bot':
|
||||
xpath = xpath_join(
|
||||
xpath, 'review[starts-with(@by_project, "openSUSE:") and @state="new"]', op='and')
|
||||
xpath = xpath_join(
|
||||
xpath, 'history/@who="{}"'.format(entity), op='and')
|
||||
|
||||
requests = search(apiurl, queries, request=xpath)['request']
|
||||
for request in requests:
|
||||
age = request_age(request)
|
||||
request_debug(request, age, threshold)
|
||||
|
||||
if age <= threshold:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
xpath = xpath_join(
|
||||
xpath, 'review[@by_{}="{}" and @state="new"]'.format(entity_type, entity), op='and')
|
||||
requests = search(apiurl, queries, request=xpath)['request']
|
||||
|
||||
print_debug('{:,} requests'.format(len(requests)))
|
||||
if not len(requests):
|
||||
# Could check to see that a review has been performed in the last week.
|
||||
return True
|
||||
|
||||
if not comment:
|
||||
return False
|
||||
|
||||
all_comment = True
|
||||
for request in requests:
|
||||
kwargs = {}
|
||||
if comment == 'project':
|
||||
# Would be a lot easier with lxml, but short of reparsing or monkey.
|
||||
for review in request.findall('review[@by_project]'):
|
||||
if review.get('by_project').startswith('openSUSE:'):
|
||||
kwargs['project_name'] = review.get('by_project')
|
||||
# TODO repo-checker will miss stagings where delete only problem so
|
||||
# comment on request, but should be fixed by #1084.
|
||||
elif comment:
|
||||
kwargs['request_id'] = request.get('id')
|
||||
|
||||
age = request_age(request)
|
||||
request_debug(request, age, threshold)
|
||||
comment_age = check_comment(apiurl, bot, **kwargs)
|
||||
if comment_age:
|
||||
if comment_age <= threshold:
|
||||
print_debug('comment found below threshold')
|
||||
return True
|
||||
elif age > threshold:
|
||||
print_debug('no comment found and above threshold')
|
||||
all_comment = False
|
||||
if threshold_require:
|
||||
return False
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
print_debug('no comment found, but below threshold')
|
||||
|
||||
print_debug('all comments: {}'.format(all_comment))
|
||||
return all_comment
|
||||
|
||||
|
||||
def status(apiurl):
|
||||
# TODO If request ordering via api (openSUSE/open-build-service#4108) is
|
||||
# provided this can be implemented much more cleanly by looking for positive
|
||||
# activity (review changes) in threshold. Without sorting, some sampling of
|
||||
# all requests accepted are returned which is not useful.
|
||||
# TODO legal-auto, does not make comments so pending the above.
|
||||
bots = [
|
||||
# No open requests older than 2 hours.
|
||||
['factory-auto'],
|
||||
# No open requests older than 2 hours or all old requests have comment.
|
||||
['leaper', 'user', True, 'Leaper'],
|
||||
# As long as some comment made in last 6 hours.
|
||||
['repo-checker', 'user', 'project', 'RepoChecker', 6 * 3600, False],
|
||||
# Different algorithm, any staging in last 24 hours.
|
||||
['staging-bot', 'user', False, None, 24 * 3600],
|
||||
]
|
||||
|
||||
for bot in bots:
|
||||
print('{} = {}'.format(bot[0], check(apiurl, *bot)))
|
||||
|
||||
def main(args):
|
||||
conf.get_config(override_apiurl=args.apiurl)
|
||||
conf.config['debug'] = args.debug
|
||||
apiurl = conf.config['apiurl']
|
||||
status(apiurl)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
description = 'Check the status of the staging workflow bots.'
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('-A', '--apiurl', help='OBS instance API URL')
|
||||
parser.add_argument('-d', '--debug', action='store_true', help='print useful debugging info')
|
||||
parser.add_argument('-p', '--project', default='openSUSE:Factory', help='OBS project')
|
||||
args = parser.parse_args()
|
||||
|
||||
sys.exit(main(args))
|
Loading…
x
Reference in New Issue
Block a user