diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-01-19 19:16:57 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-01-19 19:16:57 +0200 |
commit | 66fe1de8368ba7e754fa6dad798bf351f3c3bf93 (patch) | |
tree | e1e410beeaa3264212f2760debfbcfeebd46c50d /ick2 | |
parent | 3bc16ac24091009e73d9c4b9c2fbda0cdca6cff5 (diff) | |
download | ick2-66fe1de8368ba7e754fa6dad798bf351f3c3bf93.tar.gz |
Change: builds are now numbered foo/123, as are logs
Diffstat (limited to 'ick2')
-rw-r--r-- | ick2/apibase.py | 13 | ||||
-rw-r--r-- | ick2/buildsapi.py | 29 | ||||
-rw-r--r-- | ick2/logapi.py | 29 | ||||
-rw-r--r-- | ick2/projectapi.py | 6 | ||||
-rw-r--r-- | ick2/projectapi_tests.py | 11 | ||||
-rw-r--r-- | ick2/state.py | 5 | ||||
-rw-r--r-- | ick2/workapi.py | 7 | ||||
-rw-r--r-- | ick2/workapi_tests.py | 16 |
8 files changed, 98 insertions, 18 deletions
diff --git a/ick2/apibase.py b/ick2/apibase.py index c0b1aa5..6fb2839 100644 --- a/ick2/apibase.py +++ b/ick2/apibase.py @@ -157,25 +157,30 @@ class ResourceApiBase(APIbase): return self._state.get_resource(self._type_name, name) def create(self, body, **kwargs): - name = self.get_resource_name(body) + resource = self.mangle_resource(body) + name = self.get_resource_name(resource) try: self._state.get_resource(self._type_name, name) except ick2.NotFound: - return self._state.add_resource(self._type_name, name, body) + return self._state.add_resource(self._type_name, name, resource) else: raise ick2.ExistsAlready(name) + def mangle_resource(self, resource): # pragma: no cover + return resource + def get_resource_name(self, resource): # pragma: no cover raise NotImplementedError() def update(self, body, name, **kwargs): - name = self.get_resource_name(body) + resource = self.mangle_resource(body) + name = self.get_resource_name(resource) try: self._state.get_resource(self._type_name, name) except ick2.NotFound: raise else: - return self._state.update_resource(self._type_name, name, body) + return self._state.update_resource(self._type_name, name, resource) def delete(self, name, **kwargs): self._state.remove_resource(self._type_name, name) diff --git a/ick2/buildsapi.py b/ick2/buildsapi.py index 9ee00b7..3441027 100644 --- a/ick2/buildsapi.py +++ b/ick2/buildsapi.py @@ -21,6 +21,35 @@ class BuildsAPI(ick2.ResourceApiBase): # pragma: no cover def __init__(self, state): super().__init__('builds', state) + def get_routes(self, path): + return [ + { + 'method': 'POST', + 'path': path, + 'callback': self.POST(self.create), + }, + { + 'method': 'GET', + 'path': path, + 'callback': self.GET(self.list), + }, + { + 'method': 'GET', + 'path': '{}/<name:path>'.format(path), + 'callback': self.GET(self.show), + }, + { + 'method': 'PUT', + 'path': '{}/<name:path>'.format(path), + 'callback': self.PUT(self.update), + }, + { + 'method': 'DELETE', + 'path': '{}/<name:path>'.format(path), + 'callback': self.DELETE(self.delete), + }, + ] + def get_resource_name(self, resource): return resource['build'] diff --git a/ick2/logapi.py b/ick2/logapi.py index 37bf6aa..fde9477 100644 --- a/ick2/logapi.py +++ b/ick2/logapi.py @@ -21,6 +21,35 @@ class LogAPI(ick2.ResourceApiBase): # pragma: no cover def __init__(self, state): super().__init__('log', state) + def get_routes(self, path): + return [ + { + 'method': 'POST', + 'path': path, + 'callback': self.POST(self.create), + }, + { + 'method': 'GET', + 'path': path, + 'callback': self.GET(self.list), + }, + { + 'method': 'GET', + 'path': '{}/<name:path>'.format(path), + 'callback': self.GET(self.show), + }, + { + 'method': 'PUT', + 'path': '{}/<name:path>'.format(path), + 'callback': self.PUT(self.update), + }, + { + 'method': 'DELETE', + 'path': '{}/<name:path>'.format(path), + 'callback': self.DELETE(self.delete), + }, + ] + def get_resource_name(self, resource): return resource['log'] diff --git a/ick2/projectapi.py b/ick2/projectapi.py index 6952d6d..6b6c4fc 100644 --- a/ick2/projectapi.py +++ b/ick2/projectapi.py @@ -22,6 +22,12 @@ class ProjectAPI(ick2.ResourceApiBase): super().__init__('projects', state) self._pi = ick2.PipelineInstances(self.get_state()) + def mangle_resource(self, resource): + new = dict(resource) + if 'next_build_id' not in new: + new['next_build_id'] = None + return new + def get_resource_name(self, resource): return resource['project'] diff --git a/ick2/projectapi_tests.py b/ick2/projectapi_tests.py index 4cca9e2..96242ef 100644 --- a/ick2/projectapi_tests.py +++ b/ick2/projectapi_tests.py @@ -58,12 +58,14 @@ class ProjectAPITests(unittest.TestCase): 'pipelines': ['build'], 'parameters': { 'foo': 'bar', - } + }, } api = self.create_api() - self.assertEqual(api.create(project), project) - self.assertEqual(api.list(), {'projects': [project]}) + new = api.create(project) + project['next_build_id'] = None + self.assertEqual(new, project) + self.assertEqual(api.list(), {'projects': [new]}) self.assertEqual(api.get_pipeline('foo', 'build'), {'status': 'idle'}) self.assertEqual(api.get_pipeline('foo', 'build'), {'status': 'idle'}) @@ -90,6 +92,7 @@ class ProjectAPITests(unittest.TestCase): project = { 'project': 'foo', 'pipelines': ['build'], + 'next_build_id': None, } api = self.create_api() api.create(project) @@ -101,6 +104,7 @@ class ProjectAPITests(unittest.TestCase): project = { 'project': 'foo', 'pipelines': ['build'], + 'next_build_id': None, } api = self.create_api() api.create(project) @@ -110,6 +114,7 @@ class ProjectAPITests(unittest.TestCase): project_v1 = { 'project': 'foo', 'pipelines': ['build'], + 'next_build_id': None, } project_v2 = dict(project_v1) project_v2['shell_steps'] = ['build it using magic'] diff --git a/ick2/state.py b/ick2/state.py index 805a034..846b113 100644 --- a/ick2/state.py +++ b/ick2/state.py @@ -14,6 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. +import base64 import glob import os @@ -42,7 +43,9 @@ class ControllerState: def get_resource_filename(self, type_name, resource_name): dirname = self.get_resource_directory(type_name) - return os.path.join(dirname, resource_name + '.yaml') + basename = base64.urlsafe_b64encode( + resource_name.encode()).decode('ascii') + return os.path.join(dirname, basename + '.yaml') def load_resources(self, type_name): assert self._statedir is not None diff --git a/ick2/workapi.py b/ick2/workapi.py index e12b0d8..b6f24f2 100644 --- a/ick2/workapi.py +++ b/ick2/workapi.py @@ -50,8 +50,11 @@ class WorkAPI(ick2.APIbase): pipeline['status'] = 'building' self._update_pipeline(project, pipeline) - build_id = project.get('build_id', 0) + 1 - project['build_id'] = build_id + next_build_id = project.get('next_build_id') + if next_build_id is None: + next_build_id = 1 + build_id = '{}/{}'.format(project['project'], next_build_id) + project['next_build_id'] = next_build_id + 1 self._projects.update_project(project) self._start_build(project, pipeline, worker, build_id) diff --git a/ick2/workapi_tests.py b/ick2/workapi_tests.py index 049e17c..fdfc601 100644 --- a/ick2/workapi_tests.py +++ b/ick2/workapi_tests.py @@ -79,7 +79,7 @@ class WorkAPITests(unittest.TestCase): self.create_worker_api() work = self.create_work_api() expected = { - 'build_id': 1, + 'build_id': 'foo/1', 'worker': 'asterix', 'project': 'foo', 'pipeline': 'build', @@ -89,7 +89,7 @@ class WorkAPITests(unittest.TestCase): 'step': { 'action': 'create_workspace', }, - 'log': '/logs/1', + 'log': '/logs/foo/1', } self.assertEqual(work.get_work('asterix'), expected) @@ -104,7 +104,7 @@ class WorkAPITests(unittest.TestCase): # Ask for some work. expected = { - 'build_id': 1, + 'build_id': 'foo/1', 'worker': 'asterix', 'project': 'foo', 'pipeline': 'build', @@ -114,13 +114,13 @@ class WorkAPITests(unittest.TestCase): 'step': { 'action': 'create_workspace', }, - 'log': '/logs/1', + 'log': '/logs/foo/1', } self.assertEqual(work.get_work('asterix'), expected) # Post a partial update. done = { - 'build_id': 1, + 'build_id': 'foo/1', 'worker': 'asterix', 'project': 'foo', 'pipeline': 'build', @@ -171,7 +171,7 @@ class WorkAPITests(unittest.TestCase): # Ask for some work. expected = { - 'build_id': 1, + 'build_id': 'foo/1', 'worker': 'asterix', 'project': 'foo', 'pipeline': 'build', @@ -181,13 +181,13 @@ class WorkAPITests(unittest.TestCase): 'step': { 'action': 'create_workspace', }, - 'log': '/logs/1', + 'log': '/logs/foo/1', } self.assertEqual(work.get_work('asterix'), expected) # Post a partial update. done = { - 'build_id': 1, + 'build_id': 'foo/1', 'worker': 'asterix', 'project': 'foo', 'pipeline': 'build', |