From 3bb259bb8990f7d47c865e2130ef8a12dec69182 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 18 Nov 2017 20:49:07 +0100 Subject: Refactor: move WorkAPI into its own module --- ick2/controllerapi.py | 205 +------------------------------------------------- 1 file changed, 1 insertion(+), 204 deletions(-) (limited to 'ick2/controllerapi.py') diff --git a/ick2/controllerapi.py b/ick2/controllerapi.py index 5d5e86d..4283e82 100644 --- a/ick2/controllerapi.py +++ b/ick2/controllerapi.py @@ -33,7 +33,7 @@ class ControllerAPI: '/builds': ick2.BuildsAPI, '/logs': ick2.LogAPI, '/projects': ProjectAPI, - '/work': WorkAPI, + '/work': ick2.WorkAPI, '/workers': ick2.WorkerAPI, } @@ -114,206 +114,3 @@ class ProjectAPI(ick2.ResourceApiBase): 'project': project, 'builds': p.get('builds', []), } - - -class WorkAPI(ick2.APIbase): - - def __init__(self, state): - super().__init__(state) - self._type_name = 'work' - - def get_routes(self, path): # pragma: no cover - return [ - { - 'method': 'GET', - 'path': '{}/'.format(path), - 'callback': self.GET(self.get_work), - }, - { - 'method': 'POST', - 'path': path, - 'callback': self.POST(self.update_work), - }, - ] - - def get_work(self, worker): - worker_state = self._get_worker(worker) - if not worker_state.get('doing'): - project, pipeline = self._pick_triggered_pipeline() - if project is None: - doing = {} - else: - pipeline['status'] = 'building' - self._update_project(project) - - build_id = self._start_build(project, pipeline, worker) - self._start_log(build_id) - - index = 0 - doing = { - 'build_id': build_id, - 'worker': worker, - 'project': project['project'], - 'pipeline': pipeline['name'], - 'step': pipeline['actions'][index], - 'step_index': index, - 'log': '/logs/{}'.format(build_id), - } - - worker_state = { - 'worker': worker, - 'doing': doing, - } - self._update_worker(worker_state) - - return worker_state['doing'] - - def _get_worker(self, worker): # pragma: no cover - try: - return self._state.get_resource('workers', worker) - except ick2.NotFound: - return { - 'worker': worker, - } - - def _update_worker(self, worker_state): - self._state.update_resource( - 'workers', worker_state['worker'], worker_state) - - def _pick_triggered_pipeline(self): - projects = self._get_projects() - for project in projects: - for pipeline in project['pipelines']: - if pipeline.get('status') == 'triggered': - return project, pipeline - return None, None - - def _get_projects(self): - return self._state.get_resources('projects') - - def _update_project(self, project): - self._state.update_resource('projects', project['project'], project) - - def update_work(self, update): - if 'worker' not in update: # pragma: no cover - raise ick2.BadUpdate('no worker specified') - - worker_state = self._get_worker(update['worker']) - doing = worker_state.get('doing', {}) - self._check_work_update(doing, update) - - project, pipeline = self._get_pipeline( - update['project'], update['pipeline']) - self._append_to_build_log(update) - - ick2.log.log( - 'trace', - msg_text='xxx update_work', - update=update, - project=project, - pipeline=pipeline, - doing=doing) - - exit_code = update.get('exit_code') - if exit_code == 0: - index = doing['step_index'] + 1 - actions = pipeline['actions'] - if index >= len(actions): - pipeline['status'] = 'idle' - doing = {} - self._finish_build(update) - else: - doing['step_index'] = index - doing['step'] = actions[index] - self._update_project(project) - - worker_state = { - 'worker': update['worker'], - 'doing': doing, - } - self._update_worker(worker_state) - elif exit_code is not None: - assert isinstance(exit_code, int) - assert exit_code != 0 - pipeline['status'] = 'idle' - self._update_project(project) - self._finish_build(update) - - worker_state = { - 'worker': update['worker'], - 'doing': {}, - } - self._update_worker(worker_state) - - def _check_work_update(self, doing, update): # pragma: no cover - must_match = ['worker', 'project', 'pipeline', 'build_id'] - for name in must_match: - if name not in update: - raise ick2.BadUpdate('{} not specified'.format(name)) - if doing.get(name) != update[name]: - raise ick2.BadUpdate( - '{} differs from current work: {} vs {}'.format( - name, doing.get(name), update[name])) - - def _get_pipeline(self, project, pipeline): # pragma: no cover - projects = self._get_projects() - for p in projects: - for pl in p['pipelines']: - if pl.get('name') == pipeline: - return p, pl - raise ick2.NotFound() - - def _start_build(self, project, pipeline, worker): - ick2.log.log('info', msg_text='Starting new build') - build_id = project.get('build_id', 0) - build_id += 1 - project['build_id'] = build_id - self._update_project(project) - build = { - 'build_id': build_id, - 'log': '/logs/{}'.format(build_id), - 'worker': worker, - 'project': project['project'], - 'pipeline': pipeline['name'], - 'status': 'building', - } - 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): - 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'])) - build['status'] = update['exit_code'] - self._state.update_resource('builds', str(update['build_id']), build) - - def create(self, *args, **kwargs): # pragma: no cover - pass - - def update(self, *args, **kwargs): # pragma: no cover - pass - - def list(self, *args, **kwargs): # pragma: no cover - pass - - def show(self, *args, **kwargs): # pragma: no cover - pass - - def delete(self, *args, **kwargs): # pragma: no cover - pass -- cgit v1.2.1