Merge pull request #806 from jberry-suse/splitter-delay
request_splitter: provide and utilize an aged attribute on requests.
This commit is contained in:
commit
62bde2f8ba
@ -387,7 +387,7 @@ def do_staging(self, subcmd, opts, *args):
|
||||
print('--move and --from must be used with explicit staging and request list')
|
||||
return
|
||||
|
||||
open_requests = api.get_open_requests()
|
||||
open_requests = api.get_open_requests({'withhistory': 1})
|
||||
if len(open_requests) == 0:
|
||||
print('No open requests to consider')
|
||||
return
|
||||
|
@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
import dateutil.parser
|
||||
import hashlib
|
||||
from lxml import etree as ET
|
||||
|
||||
@ -7,6 +9,8 @@ class RequestSplitter(object):
|
||||
self.requests = requests
|
||||
self.in_ring = in_ring
|
||||
self.mergeable_build_percent = 80
|
||||
# 55 minutes to avoid two staging bot loops of 30 minutes
|
||||
self.age_threshold = 55 * 60
|
||||
|
||||
self.requests_ignored = self.api.get_ignored_requests()
|
||||
|
||||
@ -54,14 +58,14 @@ class RequestSplitter(object):
|
||||
def filter_only(self):
|
||||
ret = []
|
||||
for request in self.requests:
|
||||
self.suppliment(request)
|
||||
self.supplement(request)
|
||||
if self.filter_check(request):
|
||||
ret.append(request)
|
||||
return ret
|
||||
|
||||
def split(self):
|
||||
for request in self.requests:
|
||||
self.suppliment(request)
|
||||
self.supplement(request)
|
||||
|
||||
if not self.filter_check(request):
|
||||
continue
|
||||
@ -83,12 +87,18 @@ class RequestSplitter(object):
|
||||
else:
|
||||
self.other.append(request)
|
||||
|
||||
def suppliment(self, request):
|
||||
def supplement(self, request):
|
||||
""" Provide additional information for grouping """
|
||||
if request.get('ignored'):
|
||||
# Only supliment once.
|
||||
return
|
||||
|
||||
history = request.find('history')
|
||||
if history is not None:
|
||||
created = dateutil.parser.parse(request.find('history').get('when'))
|
||||
delta = datetime.utcnow() - created
|
||||
request.set('aged', str(delta.total_seconds() > self.age_threshold))
|
||||
|
||||
target = request.find('./action/target')
|
||||
target_project = target.get('project')
|
||||
target_package = target.get('package')
|
||||
@ -107,9 +117,9 @@ class RequestSplitter(object):
|
||||
if request_id in self.requests_ignored:
|
||||
request.set('ignored', str(self.requests_ignored[request_id]))
|
||||
else:
|
||||
request.set('ignored', 'false')
|
||||
request.set('ignored', 'False')
|
||||
|
||||
request.set('postponed', 'false')
|
||||
request.set('postponed', 'False')
|
||||
|
||||
def ring_get(self, target_package):
|
||||
if self.api.crings:
|
||||
@ -259,7 +269,7 @@ class RequestSplitter(object):
|
||||
return
|
||||
|
||||
for request in self.grouped[group]['requests']:
|
||||
request.set('postponed', 'true')
|
||||
request.set('postponed', 'True')
|
||||
|
||||
def propose_staging(self, choose_bootstrapped):
|
||||
found = False
|
||||
@ -347,8 +357,12 @@ class Strategy(object):
|
||||
class StrategyNone(Strategy):
|
||||
def apply(self, splitter):
|
||||
splitter.filter_add('./action[not(@type="add_role" or @type="change_devel")]')
|
||||
splitter.filter_add('@ignored="false"')
|
||||
splitter.filter_add('@postponed="false"')
|
||||
# All other strategies that inherit this are not restricted by age as
|
||||
# the age restriction is used to allow other strategies to be observed.
|
||||
if type(self) is StrategyNone:
|
||||
splitter.filter_add('@aged="True"')
|
||||
splitter.filter_add('@ignored="False"')
|
||||
splitter.filter_add('@postponed="False"')
|
||||
|
||||
class StrategyRequests(Strategy):
|
||||
def apply(self, splitter):
|
||||
|
@ -549,7 +549,7 @@ class StagingAPI(object):
|
||||
self.save_file_content('{}:Staging'.format(self.project), 'dashboard', 'ignored_requests', ignore)
|
||||
|
||||
@memoize(session=True, add_invalidate=True)
|
||||
def get_open_requests(self):
|
||||
def get_open_requests(self, query_extra=None):
|
||||
"""
|
||||
Get all requests with open review for staging project
|
||||
that are not yet included in any staging project
|
||||
@ -559,14 +559,16 @@ class StagingAPI(object):
|
||||
requests = []
|
||||
|
||||
# xpath query, using the -m, -r, -s options
|
||||
where = "@by_group='{}'+and+@state='new'".format(self.cstaging_group)
|
||||
where = "@by_group='{}' and @state='new'".format(self.cstaging_group)
|
||||
projects = [format(self.project)]
|
||||
if self.cnonfree:
|
||||
projects.append(self.cnonfree)
|
||||
targets = ["target[@project='{}']".format(p) for p in projects]
|
||||
|
||||
query = "match=state/@name='review'+and+review[{}]+and+({})".format(
|
||||
where, '+or+'.join(targets))
|
||||
query = {'match': "state/@name='review' and review[{}] and ({})".format(
|
||||
where, ' or '.join(targets))}
|
||||
if query_extra is not None:
|
||||
query.update(query_extra)
|
||||
url = self.makeurl(['search', 'request'], query)
|
||||
f = http_GET(url)
|
||||
root = ET.parse(f).getroot()
|
||||
|
@ -18,6 +18,7 @@ import os
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
import urllib2
|
||||
import urlparse
|
||||
import xml.etree.cElementTree as ET
|
||||
|
||||
@ -720,7 +721,7 @@ class OBS(object):
|
||||
@GET('/search/request')
|
||||
def search_request(self, request, uri, headers):
|
||||
"""Return a search result for /search/request."""
|
||||
query = urlparse.urlparse(uri).query
|
||||
query = urllib2.unquote(urlparse.urlparse(uri).query)
|
||||
assert query in (
|
||||
"match=state/@name='review'+and+review[@by_group='factory-staging'+and+@state='new']+and+(target[@project='openSUSE:Factory']+or+target[@project='openSUSE:Factory:NonFree'])",
|
||||
"match=state/@name='review'+and+review[@by_user='factory-repo-checker'+and+@state='new']+and+(target[@project='openSUSE:Factory']+or+target[@project='openSUSE:Factory:NonFree'])"
|
||||
|
Loading…
x
Reference in New Issue
Block a user