summaryrefslogtreecommitdiff
path: root/ick2/projectapi.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@exolobe1>2018-05-13 15:30:23 +0300
committerLars Wirzenius <liw@liw.fi>2018-05-17 21:44:59 +0300
commitb11d31ef23c5dfee6bfa54afbec47fc8b8bab7b1 (patch)
tree2e6b085f8fb023d53c8ac20a97aef2c7d1c11d4b /ick2/projectapi.py
parent531dd2c50bfdfcf50bb37f57cf9fc2b69787adcf (diff)
downloadick2-b11d31ef23c5dfee6bfa54afbec47fc8b8bab7b1.tar.gz
Change: how controller stores persistent data
Replace old State class with new FilePersistentState and TransactionalState classes. Use new Resource class instead of raw dicts. Use context managers for creating, updating resources, to avoid mistakes from accidentally not saving changes. Overall persistence should now be rather simpler. This should open up a possibility for changing the controller to insert more actions into the build graph, to trigger notifcations via the workers.
Diffstat (limited to 'ick2/projectapi.py')
-rw-r--r--ick2/projectapi.py106
1 files changed, 44 insertions, 62 deletions
diff --git a/ick2/projectapi.py b/ick2/projectapi.py
index a1a4ac6..22a5bb6 100644
--- a/ick2/projectapi.py
+++ b/ick2/projectapi.py
@@ -20,7 +20,6 @@ class ProjectAPI(ick2.ResourceApiBase):
def __init__(self, state):
super().__init__('projects', state)
- self._ps = ick2.ProjectStatus(self.get_state())
def mangle_new_resource(self, resource):
new = dict(resource)
@@ -45,21 +44,6 @@ class ProjectAPI(ick2.ResourceApiBase):
trigger_path = '{}/<project>/+trigger'.format(path)
return [
{
- 'method': 'GET',
- 'path': all_statuses_path,
- 'callback': self.GET(self.get_all_statuses),
- },
- {
- 'method': 'GET',
- 'path': status_path,
- 'callback': self.GET(self.get_status),
- },
- {
- 'method': 'PUT',
- 'path': status_path,
- 'callback': self.PUT(self.set_status_callback),
- },
- {
'needs-authorization': False,
'method': 'GET',
'path': trigger_path,
@@ -67,50 +51,48 @@ class ProjectAPI(ick2.ResourceApiBase):
},
]
- def get_all_statuses(self, **kwargs): # pragma: no cover
- all_projects = self.list()
- projects = all_projects['projects']
- ick2.log.log(
- 'trace', msg_text='get_all_statuses', projects=projects)
- return {
- project['project']: self.get_status(project['project'])
- for project in projects
- }
-
- def get_status(self, project, **kwargs):
- ick2.log.log('trace', msg_text='get_status', project=project)
- _ = self._state.get_resource(self._type_name, project)
- ps = self._ps.get_instance(project)
- return {
- 'status': ps.get('status', 'idle'),
- }
-
- def set_status_callback(self, body, project, **kwargs): # pragma: no cover
- return self.set_status(project, body['status'])
-
- def set_status(self, project, status):
- ick2.log.log(
- 'trace', msg_text='Setting project status',
- project=project, status=status)
-
- allowed_changes = {
- 'idle': 'triggered',
- 'triggered': 'building',
- 'building': 'idle',
- }
-
- p = self._state.get_resource(self._type_name, project)
- ick2.log.log('trace', msg_text='Found project', project=p)
-
- ps = self._ps.get_instance(project)
- old_status = ps.get('status', 'idle')
- if allowed_changes[old_status] != status:
- raise ick2.WrongProjectStatus(status)
- ps['status'] = status
- self._ps.update_instance(project, ps)
- return {'status': status}
-
- # This needs to go away as it is not protected. Once an IDP is
- # added.
def trigger_project(self, project, **kwargs): # pragma: no cover
- return self.set_status(project, 'triggered')
+ with self._trans.modify('projects', project) as p:
+ self._start_build(p)
+ return {'status': 'triggered'}
+
+ def _start_build(self, project): # pragma: no cover
+ build_no = self._pick_build_number(project)
+ build_id = '{}/{}'.format(project['project'], build_no)
+ ick2.log.log('info', msg_text='Starting new build', build_id=build_id)
+
+ with self._trans.new('builds', build_id) as build:
+ parameters = project.get('parameters', {})
+ create_workspace = {
+ 'action': 'create_workspace',
+ 'where': 'host',
+ }
+ actions = [create_workspace] + self._get_actions(project)
+ build.from_dict({
+ 'build_id': build_id,
+ 'build_number': build_no,
+ 'log': '/logs/{}'.format(build_id),
+ 'worker': None,
+ 'project': project['project'],
+ 'parameters': parameters,
+ 'status': 'triggered',
+ 'actions': actions,
+ 'current_action': 0,
+ })
+ return build_id, build_no
+
+ def _pick_build_number(self, project): # pragma: no cover
+ old_build_no = project.get('next_build_id')
+ build_no = (old_build_no or 0) + 1
+ project['next_build_id'] = build_no
+ ick2.log.log(
+ 'info', msg_text='chose build number',
+ old_build_no=old_build_no, build_no=build_no)
+ return build_no
+
+ def _get_actions(self, project): # pragma: no cover
+ actions = []
+ for pipeline_name in project.get('pipelines', []):
+ pipeline = self._trans.get_resource('pipelines', pipeline_name)
+ actions.extend(list(pipeline['actions']))
+ return actions