diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-02-08 13:53:40 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-02-08 17:55:18 +0200 |
commit | 36cc7485688f77b339f248d5a93df148a060eaca (patch) | |
tree | 863db02a91b22d3554c4a617e013dabf90334005 | |
parent | 67fe67e0a6b1ba53551f2dd2824e91ee2adb9810 (diff) | |
download | ick2-36cc7485688f77b339f248d5a93df148a060eaca.tar.gz |
Add: controller /version reports blob service URL
-rw-r--r-- | ick2/controllerapi.py | 19 | ||||
-rw-r--r-- | ick2/versionapi.py | 14 | ||||
-rw-r--r-- | ick2/versionapi_tests.py | 9 | ||||
-rw-r--r-- | ick_controller.py | 8 | ||||
-rwxr-xr-x | worker_manager | 37 | ||||
-rw-r--r-- | yarns/100-projects.yarn | 1 | ||||
-rw-r--r-- | yarns/150-pipelines.yarn | 1 | ||||
-rw-r--r-- | yarns/200-version.yarn | 4 | ||||
-rw-r--r-- | yarns/300-workers.yarn | 3 | ||||
-rw-r--r-- | yarns/400-build.yarn | 2 | ||||
-rw-r--r-- | yarns/500-build-fail.yarn | 1 | ||||
-rw-r--r-- | yarns/600-unauthz.yarn | 1 | ||||
-rw-r--r-- | yarns/900-local.yarn | 13 |
13 files changed, 89 insertions, 24 deletions
diff --git a/ick2/controllerapi.py b/ick2/controllerapi.py index fe28c29..074fa2e 100644 --- a/ick2/controllerapi.py +++ b/ick2/controllerapi.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Lars Wirzenius +# Copyright (C) 2017-2018 Lars Wirzenius # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -20,6 +20,16 @@ class ControllerAPI: def __init__(self, state): self._state = state + self._apis = {} + + def set_blob_service_url(self, url): # pragma: no cover + self.find_missing_route('/version') + api = self._apis.get('/version') + if api: + api.set_blob_service_url(url) + ick2.log.log( + 'info', msg_text='Set blob service url', url=url, + version=api.get_version()) def find_missing_route(self, missing_path): # pragma: no cover apis = { @@ -32,10 +42,13 @@ class ControllerAPI: '/workers': ick2.WorkerAPI, } - routes = [] for path in apis: + if path not in self._apis: + self._apis[path] = apis[path](self._state) + + routes = [] + for path, api in self._apis.items(): self._state.load_resources(path[1:]) - api = apis[path](self._state) routes.extend(api.get_routes(path)) ick2.log.log('info', msg_texg='Found routes', routes=routes) return routes diff --git a/ick2/versionapi.py b/ick2/versionapi.py index fddfdcc..40d1dda 100644 --- a/ick2/versionapi.py +++ b/ick2/versionapi.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Lars Wirzenius +# Copyright (C) 2017-2018 Lars Wirzenius # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -18,6 +18,13 @@ import ick2 class VersionAPI(ick2.APIbase): + def __init__(self, state): + super().__init__(state) + self._blob_service_url = None + + def set_blob_service_url(self, url): + self._blob_service_url = url + def get_routes(self, path): # pragma: no cover return [ { @@ -28,7 +35,10 @@ class VersionAPI(ick2.APIbase): ] def get_version(self, **kwargs): - return {'version': ick2.__version__} + return { + 'version': ick2.__version__, + 'blob_service': self._blob_service_url, + } def create(self, body, **kwargs): # pragma: no cover pass diff --git a/ick2/versionapi_tests.py b/ick2/versionapi_tests.py index 500d7e6..143e1cc 100644 --- a/ick2/versionapi_tests.py +++ b/ick2/versionapi_tests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Lars Wirzenius +# Copyright (C) 2017-2018 Lars Wirzenius # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -21,16 +21,15 @@ import ick2 class VersionAPITests(unittest.TestCase): - def create_api(self): - api = ick2.VersionAPI(None) - return api - def test_returns_version_correcly(self): + bloburl = 'https://blobs.example.com' api = ick2.VersionAPI(None) + api.set_blob_service_url(bloburl) response = api.get_version() self.assertEqual( response, { 'version': ick2.__version__, + 'blob_service': bloburl, } ) diff --git a/ick_controller.py b/ick_controller.py index 85c0bca..a176351 100644 --- a/ick_controller.py +++ b/ick_controller.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -# Copyright (C) 2017 Lars Wirzenius +# Copyright (C) 2017-2018 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -46,6 +46,7 @@ default_config = { 'token-issuer': None, 'log': [], 'statedir': None, + 'blob-service': None, } @@ -93,7 +94,10 @@ def main(): state.set_state_directory(config['statedir']) api = ick2.ControllerAPI(state) - ick2.log.log('info', msg_text='created ControllerAPI') + api.set_blob_service_url(config['blob-service']) + ick2.log.log( + 'info', msg_text='created ControllerAPI', + blob_service=config['blob-service']) application = apifw.create_bottle_application( api, counter, dict_logger, config) diff --git a/worker_manager b/worker_manager index efb84cd..5e0b0f3 100755 --- a/worker_manager +++ b/worker_manager @@ -120,6 +120,7 @@ class ControllerAPI: def __init__(self, name, url, token_generator): self._name = name self._url = url + self._blob_url = None self._token_generator = token_generator self._httpapi = HttpApi() @@ -149,26 +150,42 @@ class ControllerAPI: raise cliapp.AppException( 'Error posting data to controller: {}'.format(code)) + def url(self, path): + return '{}{}'.format(self._url, path) + + def get_auth_headers(self): + token = self._token_generator.get_token() + return { + 'Authorization': 'Bearer {}'.format(token), + } + def upload_blob(self, blob_id, blob): logging.info('Upload blob %s', blob_id) - url = self.url('/blobs/{}'.format(blob_id)) + url = self.bloburl(blob_id) headers = self.get_auth_headers() code = self._httpapi.put(url, headers, blob) def download_blob(self, blob_id): logging.info('Download blob %s', blob_id) - url = self.url('/blobs/{}'.format(blob_id)) + url = self.bloburl(blob_id) headers = self.get_auth_headers() return self._httpapi.get_blob(url, headers) - def url(self, path): - return '{}{}'.format(self._url, path) + def bloburl(self, blob_id): + if self._blob_url is None: + self._blob_url = self.get_blob_service_url() + if self._blob_url is not None: + return '{}/blobs/{}'.format(self._blob_url, blob_id) + logging.error('Do not have blob service URL') + return None - def get_auth_headers(self): - token = self._token_generator.get_token() - return { - 'Authorization': 'Bearer {}'.format(token), - } + def get_blob_service_url(self): + url = self.url('/version') + headers = self.get_auth_headers() + version = self._httpapi.get(url, headers) + if version: + logging.info('Version: %r', version) + return version['blob_service'] class HttpApi: @@ -541,7 +558,7 @@ class WorkspaceArchiver(WorkerBase): logging.info('Uploading %s', blob_id) self.report(b'Uploading workspace\n') - url = self._api.url('/blobs/{}'.format(blob_id)) + url = self._api.bloburl('/blobs/{}'.format(blob_id)) headers = self._api.get_auth_headers() upload = ['curl', '-sk', '-T', filename] for name, value in headers.items(): diff --git a/yarns/100-projects.yarn b/yarns/100-projects.yarn index 63572e7..7c18952 100644 --- a/yarns/100-projects.yarn +++ b/yarns/100-projects.yarn @@ -55,6 +55,7 @@ building them. We start by starting an instance of the controller. ... uapi_projects_id_put ... uapi_projects_id_delete AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND a running ick controller WHEN user makes request GET /projects diff --git a/yarns/150-pipelines.yarn b/yarns/150-pipelines.yarn index 7169dd5..feda6d0 100644 --- a/yarns/150-pipelines.yarn +++ b/yarns/150-pipelines.yarn @@ -63,6 +63,7 @@ running them. We start by starting an instance of the controller. ... uapi_pipelines_id_put ... uapi_pipelines_id_delete AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND a running ick controller WHEN user makes request GET /pipelines diff --git a/yarns/200-version.yarn b/yarns/200-version.yarn index fe92b34..2f87ac7 100644 --- a/yarns/200-version.yarn +++ b/yarns/200-version.yarn @@ -1,6 +1,6 @@ <!-- -Copyright 2017 Lars Wirzenius +Copyright 2017-2018 Lars Wirzenius This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -26,11 +26,13 @@ The Ick controller reports is version upon request. AND an access token for user with scopes ... uapi_version_get AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND a running ick controller WHEN user makes request GET /version THEN result has status code 200 AND version in body matches version from setup.py + AND blob service URL is https://blobs.example.com FINALLY stop ick controller diff --git a/yarns/300-workers.yarn b/yarns/300-workers.yarn index c94f47c..2cc7ea2 100644 --- a/yarns/300-workers.yarn +++ b/yarns/300-workers.yarn @@ -1,6 +1,6 @@ <!-- -Copyright 2017 Lars Wirzenius +Copyright 2017-2018 Lars Wirzenius This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -60,6 +60,7 @@ controller API. It doesn't actually talk to the worker itself. ... uapi_workers_id_put ... uapi_workers_id_delete AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND a running ick controller WHEN user makes request GET /workers diff --git a/yarns/400-build.yarn b/yarns/400-build.yarn index e0af107..5de9768 100644 --- a/yarns/400-build.yarn +++ b/yarns/400-build.yarn @@ -27,6 +27,7 @@ Set up the controller. GIVEN an RSA key pair for token signing AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND an access token for user with scopes ... uapi_pipelines_post ... uapi_projects_post @@ -639,6 +640,7 @@ Set up the controller. GIVEN an RSA key pair for token signing AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND an access token for user with scopes ... uapi_pipelines_post ... uapi_projects_post diff --git a/yarns/500-build-fail.yarn b/yarns/500-build-fail.yarn index cde859f..dcc551d 100644 --- a/yarns/500-build-fail.yarn +++ b/yarns/500-build-fail.yarn @@ -28,6 +28,7 @@ Set up the controller. GIVEN an RSA key pair for token signing AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND an access token for user with scopes ... uapi_pipelines_post ... uapi_projects_post diff --git a/yarns/600-unauthz.yarn b/yarns/600-unauthz.yarn index e8d9664..0a602af 100644 --- a/yarns/600-unauthz.yarn +++ b/yarns/600-unauthz.yarn @@ -28,6 +28,7 @@ Set up the controller. GIVEN an RSA key pair for token signing AND controller config uses statedir at the state directory + AND controller config uses https://blobs.example.com as blob service AND an access token for user with scopes ... uapi_projects_post ... uapi_projects_id_pipelines_id_put diff --git a/yarns/900-local.yarn b/yarns/900-local.yarn index 2739542..5efad69 100644 --- a/yarns/900-local.yarn +++ b/yarns/900-local.yarn @@ -46,6 +46,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. IMPLEMENTS GIVEN controller config uses (\S+) at the state directory vars['statedir'] = get_next_match() + IMPLEMENTS GIVEN controller config uses (\S+) as blob service + vars['blob_service'] = get_next_match() + ## Start and stop the controller IMPLEMENTS GIVEN a running ick controller @@ -64,6 +67,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. }, ], 'statedir': vars['statedir'], + 'blob-service': vars['blob_service'], } env = dict(os.environ) env['ICK_CONTROLLER_CONFIG'] = 'ick_controller.yaml' @@ -103,6 +107,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. filename = os.path.join(vars['statedir'], 'workers', basename + '.yaml') assertTrue(os.path.exists(filename)) +## Check version result + + IMPLEMENTS THEN blob service URL is (\S+) + expected = get_next_match() + body = vars['body'] + obj = json.loads(body) + actual = obj['blob_service'] + assertEqual(actual, expected) + ## Start and stop blob service IMPLEMENTS GIVEN blob service config uses (\S+) at the blob directory |