From 917ba8f58479147e773b4a02400e280e1e4a8dff Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 6 Nov 2017 13:41:52 +0100 Subject: Add: update, retrieve build logs --- ick2/controllerapi.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'ick2/controllerapi.py') diff --git a/ick2/controllerapi.py b/ick2/controllerapi.py index 5cf5d64..c72c300 100644 --- a/ick2/controllerapi.py +++ b/ick2/controllerapi.py @@ -34,6 +34,7 @@ class ControllerAPI: apis = { '/version': VersionAPI, '/builds': BuildsAPI, + '/log': LogAPI, '/projects': ProjectAPI, '/work': WorkAPI, '/workers': WorkerAPI, @@ -93,7 +94,11 @@ class APIbase: # pragma: no cover body = callback(**kwargs) except ick2.NotFound as e: return not_found(e) - return OK(body) + if isinstance(body, dict): + return OK(body) + elif isinstance(body, str): + return text_plain(body) + raise Exception('this must not happen') return wrapper def POST(self, callback): @@ -242,6 +247,26 @@ class BuildsAPI(ResourceApiBase): # pragma: no cover raise MethodNotAllowed('Updating builds directly is not allowed') +class LogAPI(ResourceApiBase): # pragma: no cover + + def __init__(self, state): + super().__init__('log', state) + + def get_resource_name(self, resource): + return resource['log'] + + def create(self, body): # pragma: no cover + raise MethodNotAllowed('Creating builds directly is not allowed') + + def update(self, body, name): # pragma: no cover + raise MethodNotAllowed('Updating builds directly is not allowed') + + def show(self, name): + log = self._state.get_resource('log', str(name)) + ick2.log.log('info', msg_text='Returning log', log=log) + return log['log'] + + class ProjectAPI(ResourceApiBase): def __init__(self, state): @@ -343,6 +368,7 @@ class WorkAPI(APIbase): self._update_project(project) build_id = self._start_build(project, pipeline, worker) + self._start_log(build_id) index = 0 doing = { @@ -352,6 +378,7 @@ class WorkAPI(APIbase): 'pipeline': pipeline['name'], 'step': pipeline['actions'][index], 'step_index': index, + 'log': '/log/{}'.format(build_id), } worker_state = { @@ -450,6 +477,7 @@ class WorkAPI(APIbase): build_id = 1 build = { 'build_id': build_id, + 'log': '/log/{}'.format(build_id), 'worker': worker, 'project': project['project'], 'pipeline': pipeline['name'], @@ -458,8 +486,23 @@ class WorkAPI(APIbase): self._state.add_resource('builds', str(build_id), build) return build_id + def _start_log(self, build_id): + ick2.log.log('info', msg_text='Starting new log', build_id=build_id) + log = { + 'build_id': build_id, + 'log': '', + } + self._state.add_resource('log', str(build_id), log) + return build_id + def _append_to_build_log(self, update): - pass + build_id = update['build_id'] + log = self._state.get_resource('log', str(build_id)) + for kind in ['stdout', 'stderr']: + text = update.get(kind, '') + if text is not None: + log['log'] += text + self._state.update_resource('log', str(build_id), log) def _finish_build(self, update): build = self._state.get_resource('builds', str(update['build_id'])) @@ -510,6 +553,13 @@ def OK(body): # pragma: no cover return response(apifw.HTTP_OK, body, headers) +def text_plain(body): # pragma: no cover + headers = { + 'Content-Type': 'text/plain', + } + return response(apifw.HTTP_OK, body, headers) + + def not_found(error): # pragma: no cover headers = { 'Content-Type': 'text/plain', -- cgit v1.2.1