From c6ca548116a839f6cb5f60d0e330c14a5d86c00e Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Fri, 19 Jan 2018 12:58:14 -0600 Subject: [PATCH] Port per-change status to zuul-web Also, re-enable the test for it. Change-Id: I121fce92cc01018e4e95cd3cda54948415a0d55a --- tests/unit/test_web.py | 1 - zuul/web/__init__.py | 44 +++++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_web.py b/tests/unit/test_web.py index 35827a0d18..7f9e651a5e 100644 --- a/tests/unit/test_web.py +++ b/tests/unit/test_web.py @@ -184,7 +184,6 @@ class TestWeb(ZuulTestCase): "http://localhost:%s/status/foo" % self.port) self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, req) - @skip("This is not supported by zuul-web") def test_web_find_change(self): # can we filter by change id req = urllib.request.Request( diff --git a/zuul/web/__init__.py b/zuul/web/__init__.py index abe9bfa4cd..08df42a467 100755 --- a/zuul/web/__init__.py +++ b/zuul/web/__init__.py @@ -16,6 +16,7 @@ import asyncio +import copy import json import logging import os @@ -158,41 +159,45 @@ class GearmanHandler(object): 'key_get': self.key_get, } - async def tenant_list(self, request): + async def tenant_list(self, request, result_filter=None): job = self.rpc.submitJob('zuul:tenant_list', {}) return web.json_response(json.loads(job.data[0])) - async def status_get(self, request): + async def status_get(self, request, result_filter=None): tenant = request.match_info["tenant"] if tenant not in self.cache or \ (time.time() - self.cache_time[tenant]) > self.cache_expiry: job = self.rpc.submitJob('zuul:status_get', {'tenant': tenant}) self.cache[tenant] = json.loads(job.data[0]) self.cache_time[tenant] = time.time() - resp = web.json_response(self.cache[tenant]) + payload = self.cache[tenant] + if result_filter: + payload = result_filter.filterPayload(payload) + resp = web.json_response(payload) resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers["Cache-Control"] = "public, max-age=%d" % \ self.cache_expiry resp.last_modified = self.cache_time[tenant] return resp - async def job_list(self, request): + async def job_list(self, request, result_filter=None): tenant = request.match_info["tenant"] job = self.rpc.submitJob('zuul:job_list', {'tenant': tenant}) resp = web.json_response(json.loads(job.data[0])) resp.headers['Access-Control-Allow-Origin'] = '*' return resp - async def key_get(self, request): + async def key_get(self, request, result_filter=None): tenant = request.match_info["tenant"] project = request.match_info["project"] job = self.rpc.submitJob('zuul:key_get', {'tenant': tenant, 'project': project}) return web.Response(body=job.data[0]) - async def processRequest(self, request, action): + async def processRequest(self, request, action, result_filter=None): + resp = None try: - resp = await self.controllers[action](request) + resp = await self.controllers[action](request, result_filter) except asyncio.CancelledError: self.log.debug("request handling cancelled") except Exception as e: @@ -202,6 +207,24 @@ class GearmanHandler(object): return resp +class ChangeFilter(object): + def __init__(self, desired): + self.desired = desired + + def filterPayload(self, payload): + status = [] + for pipeline in payload['pipelines']: + for change_queue in pipeline['change_queues']: + for head in change_queue['heads']: + for change in head: + if self.wantChange(change): + status.append(copy.deepcopy(change)) + return status + + def wantChange(self, change): + return change['id'] == self.desired + + class ZuulWeb(object): log = logging.getLogger("zuul.web.ZuulWeb") @@ -238,6 +261,11 @@ class ZuulWeb(object): async def _handleStatusRequest(self, request): return await self.gearman_handler.processRequest(request, 'status_get') + async def _handleStatusChangeRequest(self, request): + change = request.match_info["change"] + return await self.gearman_handler.processRequest( + request, 'status_get', ChangeFilter(change)) + async def _handleJobsRequest(self, request): return await self.gearman_handler.processRequest(request, 'job_list') @@ -259,6 +287,8 @@ class ZuulWeb(object): ('GET', '/tenants', self._handleTenantsRequest), ('GET', '/{tenant}/status', self._handleStatusRequest), ('GET', '/{tenant}/jobs', self._handleJobsRequest), + ('GET', '/{tenant}/status/change/{change}', + self._handleStatusChangeRequest), ('GET', '/{tenant}/console-stream', self._handleWebsocket), ('GET', '/{tenant}/{project:.*}.pub', self._handleKeyRequest), ]