summaryrefslogtreecommitdiff
path: root/ick2/controllerapi.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2017-11-18 20:49:07 +0100
committerLars Wirzenius <liw@liw.fi>2017-11-18 20:49:07 +0100
commit3bb259bb8990f7d47c865e2130ef8a12dec69182 (patch)
treeffe681e452624e85acea0e7c911941ff5ea065f7 /ick2/controllerapi.py
parent5f26bbcc37eb4bf78c1ab1e231a55ec98f2e3d4e (diff)
downloadick2-3bb259bb8990f7d47c865e2130ef8a12dec69182.tar.gz
Refactor: move WorkAPI into its own module
Diffstat (limited to 'ick2/controllerapi.py')
-rw-r--r--ick2/controllerapi.py205
1 files changed, 1 insertions, 204 deletions
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': '{}/<worker>'.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