From ba44d1c384c58ae8059a44c0ef0afaacba40225f Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Mon, 28 Nov 2011 14:37:58 +0000 Subject: [PATCH] Add generic PasteDeploy app and filter factories These generic factories allow us to dump the copied and pasted app_factory and filter_factory methods in the codebase. The main difference is the paste configuration changes from: [app:apiv1app] paste.app_factory = glance.api.v1:app_factory ... [filter:cache] paste.filter_factory = glance.api.middleware.cache:filter_factory to this: [app:apiv1app] paste.app_factory = glance.common.wsgi:app_factory glance.app_factory = glance.api.v1:API ... [filter:cache] paste.filter_factory = glance.common.wsgi:filter_factory glance.filter_factory = glance.api.middleware.cache:CacheFilter Apart from reducing code duplication, this will also allow us to have the generic factories inject other data into the apps and filters. Change-Id: I1d2be5630ab61d29b8948ff88d58e6e1b11c2e5f --- doc/source/configuring.rst | 3 +- etc/glance-api.conf | 18 ++++--- etc/glance-cache.conf | 12 +++-- etc/glance-registry.conf | 9 ++-- etc/glance-scrubber.conf | 3 +- glance/api/cached_images.py | 7 --- glance/api/middleware/cache.py | 13 ----- glance/api/middleware/cache_manage.py | 13 ----- glance/api/middleware/version_negotiation.py | 13 ----- glance/api/v1/router.py | 7 --- glance/common/context.py | 13 ----- glance/common/wsgi.py | 50 +++++++++++++++++++ glance/image_cache/cleaner.py | 6 --- glance/image_cache/prefetcher.py | 6 --- glance/image_cache/pruner.py | 6 --- glance/image_cache/queue_image.py | 6 --- glance/registry/api/v1/__init__.py | 10 ---- glance/registry/server.py | 20 -------- glance/store/scrubber.py | 6 --- glance/tests/functional/__init__.py | 25 +++++++--- glance/tests/functional/keystone_utils.py | 4 +- .../test_bin_glance_cache_manage.py | 12 +++-- .../tests/functional/test_cache_middleware.py | 12 +++-- glance/tests/unit/test_config.py | 3 +- 24 files changed, 118 insertions(+), 159 deletions(-) delete mode 100644 glance/registry/server.py diff --git a/doc/source/configuring.rst b/doc/source/configuring.rst index fe479bec99..b9c168d2cd 100644 --- a/doc/source/configuring.rst +++ b/doc/source/configuring.rst @@ -513,7 +513,8 @@ The cache middleware should be in your ``glance-api.conf`` in a section titled ``[filter:cache]``. It should look like this:: [filter:cache] - paste.filter_factory = glance.api.middleware.cache:filter_factory + paste.filter_factory = glance.common.wsgi:filter_factory + glance.filter_factory = glance.api.middleware.cache:CacheFilter For example, suppose your application pipeline in the ``glance-api.conf`` file diff --git a/etc/glance-api.conf b/etc/glance-api.conf index 78ca42150b..3851d4406e 100644 --- a/etc/glance-api.conf +++ b/etc/glance-api.conf @@ -214,19 +214,24 @@ pipeline = versionnegotiation context apiv1app # pipeline = versionnegotiation authtoken auth-context cachemanage apiv1app [app:apiv1app] -paste.app_factory = glance.api.v1.router:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.api.v1.router:API [filter:versionnegotiation] -paste.filter_factory = glance.api.middleware.version_negotiation:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter [filter:cache] -paste.filter_factory = glance.api.middleware.cache:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.api.middleware.cache:CacheFilter [filter:cachemanage] -paste.filter_factory = glance.api.middleware.cache_manage:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter [filter:context] -paste.filter_factory = glance.common.context:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.common.context:ContextMiddleware [filter:authtoken] paste.filter_factory = keystone.middleware.auth_token:filter_factory @@ -240,4 +245,5 @@ auth_uri = http://127.0.0.1:5000/ admin_token = 999888777666 [filter:auth-context] -paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = keystone.middleware.glance_auth_token:KeystoneContextMiddleware diff --git a/etc/glance-cache.conf b/etc/glance-cache.conf index dc48af55a4..d7694c76fd 100644 --- a/etc/glance-cache.conf +++ b/etc/glance-cache.conf @@ -40,13 +40,17 @@ registry_port = 9191 # admin_token = 123 [app:glance-pruner] -paste.app_factory = glance.image_cache.pruner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.pruner:Pruner [app:glance-prefetcher] -paste.app_factory = glance.image_cache.prefetcher:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.prefetcher:Prefetcher [app:glance-cleaner] -paste.app_factory = glance.image_cache.cleaner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.cleaner:Cleaner [app:glance-queue-image] -paste.app_factory = glance.image_cache.queue_image:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.queue_image:Queuer diff --git a/etc/glance-registry.conf b/etc/glance-registry.conf index ce8af759c0..c9d32cbbcf 100644 --- a/etc/glance-registry.conf +++ b/etc/glance-registry.conf @@ -57,11 +57,13 @@ pipeline = context registryapp # pipeline = authtoken auth-context registryapp [app:registryapp] -paste.app_factory = glance.registry.api.v1:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.registry.api.v1:API [filter:context] context_class = glance.registry.context.RequestContext -paste.filter_factory = glance.common.context:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.common.context:ContextMiddleware [filter:authtoken] paste.filter_factory = keystone.middleware.auth_token:filter_factory @@ -76,4 +78,5 @@ admin_token = 999888777666 [filter:auth-context] context_class = glance.registry.context.RequestContext -paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = keystone.middleware.glance_auth_token:KeystoneContextMiddleware diff --git a/etc/glance-scrubber.conf b/etc/glance-scrubber.conf index 0dcc8aaac8..ade7da6ff7 100644 --- a/etc/glance-scrubber.conf +++ b/etc/glance-scrubber.conf @@ -35,4 +35,5 @@ registry_host = 0.0.0.0 registry_port = 9191 [app:glance-scrubber] -paste.app_factory = glance.store.scrubber:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.store.scrubber:Scrubber diff --git a/glance/api/cached_images.py b/glance/api/cached_images.py index fc643a1bd3..7efe1139c3 100644 --- a/glance/api/cached_images.py +++ b/glance/api/cached_images.py @@ -115,10 +115,3 @@ def create_resource(options): deserializer = CachedImageDeserializer() serializer = CachedImageSerializer() return wsgi.Resource(Controller(options), deserializer, serializer) - - -def app_factory(global_conf, **local_conf): - """paste.deploy app factory for creating Cached Images apps""" - conf = global_conf.copy() - conf.update(local_conf) - return Controller(conf) diff --git a/glance/api/middleware/cache.py b/glance/api/middleware/cache.py index 0c43dc4897..ce79f0bbc8 100644 --- a/glance/api/middleware/cache.py +++ b/glance/api/middleware/cache.py @@ -132,16 +132,3 @@ class CacheFilter(wsgi.Middleware): chunks = utils.chunkiter(cache_file) for chunk in chunks: yield chunk - - -def filter_factory(global_conf, **local_conf): - """ - Factory method for paste.deploy - """ - conf = global_conf.copy() - conf.update(local_conf) - - def filter(app): - return CacheFilter(app, conf) - - return filter diff --git a/glance/api/middleware/cache_manage.py b/glance/api/middleware/cache_manage.py index c1142ae747..285d180ffd 100644 --- a/glance/api/middleware/cache_manage.py +++ b/glance/api/middleware/cache_manage.py @@ -70,16 +70,3 @@ class CacheManageFilter(wsgi.Middleware): logger.info(_("Initialized image cache management middleware")) super(CacheManageFilter, self).__init__(app) - - -def filter_factory(global_conf, **local_conf): - """ - Factory method for paste.deploy - """ - conf = global_conf.copy() - conf.update(local_conf) - - def filter(app): - return CacheManageFilter(app, conf) - - return filter diff --git a/glance/api/middleware/version_negotiation.py b/glance/api/middleware/version_negotiation.py index 05aa39717f..9605feb63b 100644 --- a/glance/api/middleware/version_negotiation.py +++ b/glance/api/middleware/version_negotiation.py @@ -121,16 +121,3 @@ class VersionNegotiationFilter(wsgi.Middleware): req.environ['api.major_version'] = major_version req.environ['api.minor_version'] = minor_version return match is not None - - -def filter_factory(global_conf, **local_conf): - """ - Factory method for paste.deploy - """ - conf = global_conf.copy() - conf.update(local_conf) - - def filter(app): - return VersionNegotiationFilter(app, conf) - - return filter diff --git a/glance/api/v1/router.py b/glance/api/v1/router.py index 65130c4b4d..4a9613eb94 100644 --- a/glance/api/v1/router.py +++ b/glance/api/v1/router.py @@ -56,10 +56,3 @@ class API(wsgi.Router): conditions=dict(method=["PUT"])) super(API, self).__init__(mapper) - - -def app_factory(global_conf, **local_conf): - """paste.deploy app factory for creating Glance API server apps""" - conf = global_conf.copy() - conf.update(local_conf) - return API(conf) diff --git a/glance/common/context.py b/glance/common/context.py index af2b77477c..f6c4d5e5e9 100644 --- a/glance/common/context.py +++ b/glance/common/context.py @@ -119,16 +119,3 @@ class ContextMiddleware(wsgi.Middleware): req.context = self.make_context( auth_tok=auth_tok, user=user, tenant=tenant, roles=roles, is_admin=is_admin) - - -def filter_factory(global_conf, **local_conf): - """ - Factory method for paste.deploy - """ - conf = global_conf.copy() - conf.update(local_conf) - - def filter(app): - return ContextMiddleware(app, conf) - - return filter diff --git a/glance/common/wsgi.py b/glance/common/wsgi.py index 58767243a2..89fe0f1a70 100644 --- a/glance/common/wsgi.py +++ b/glance/common/wsgi.py @@ -37,6 +37,7 @@ import webob.dec import webob.exc from glance.common import exception +from glance.common import utils class WritableLogger(object): @@ -406,3 +407,52 @@ class Resource(object): pass return args + + +def _import_factory(conf, key): + return utils.import_class(conf[key].replace(':', '.').strip()) + + +def app_factory(global_conf, **local_conf): + """A Generic paste.deploy app factory. + + This requires glance.app_factory to be set to a callable which returns a + WSGI app when invoked. The format of the name is : e.g. + + [app:apiv1app] + paste.app_factory = glance.common.wsgi:app_factory + glance.app_factory = glance.api.v1:API + + The WSGI app constructor must accept a configuration dict as its only + argument. + """ + factory = _import_factory(local_conf, 'glance.app_factory') + + conf = global_conf.copy() + conf.update(local_conf) + + return factory(conf) + + +def filter_factory(global_conf, **local_conf): + """A Generic paste.deploy filter factory. + + This requires glance.filter_factory to be set to a callable which returns a + WSGI filter when invoked. The format is : e.g. + + [filter:cache] + paste.filter_factory = glance.common.wsgi:filter_factory + glance.filter_factory = glance.api.middleware.cache:CacheFilter + + The WSGI filter constructor must accept a WSGI app and a configuration dict + as its only two arguments. + """ + factory = _import_factory(local_conf, 'glance.filter_factory') + + conf = global_conf.copy() + conf.update(local_conf) + + def filter(app): + return factory(app, conf) + + return filter diff --git a/glance/image_cache/cleaner.py b/glance/image_cache/cleaner.py index 8b3656eca4..adced3360c 100644 --- a/glance/image_cache/cleaner.py +++ b/glance/image_cache/cleaner.py @@ -33,9 +33,3 @@ class Cleaner(object): def run(self): self.cache.clean() - - -def app_factory(global_config, **local_conf): - conf = global_config.copy() - conf.update(local_conf) - return Cleaner(conf) diff --git a/glance/image_cache/prefetcher.py b/glance/image_cache/prefetcher.py index d2f90cc4cf..faacba559e 100644 --- a/glance/image_cache/prefetcher.py +++ b/glance/image_cache/prefetcher.py @@ -88,9 +88,3 @@ class Prefetcher(object): logger.info(_("Successfully cached all %d images"), num_images) return True - - -def app_factory(global_config, **local_conf): - conf = global_config.copy() - conf.update(local_conf) - return Prefetcher(conf) diff --git a/glance/image_cache/pruner.py b/glance/image_cache/pruner.py index 77e039234d..01583f62e8 100644 --- a/glance/image_cache/pruner.py +++ b/glance/image_cache/pruner.py @@ -33,9 +33,3 @@ class Pruner(object): def run(self): self.cache.prune() - - -def app_factory(global_config, **local_conf): - conf = global_config.copy() - conf.update(local_conf) - return Pruner(conf) diff --git a/glance/image_cache/queue_image.py b/glance/image_cache/queue_image.py index 683b9e0f99..d60c2b7b9a 100644 --- a/glance/image_cache/queue_image.py +++ b/glance/image_cache/queue_image.py @@ -78,9 +78,3 @@ class Queuer(object): logger.info(_("Successfully queued all %d images"), num_images) return True - - -def app_factory(global_config, **local_conf): - conf = global_config.copy() - conf.update(local_conf) - return Queuer(conf) diff --git a/glance/registry/api/v1/__init__.py b/glance/registry/api/v1/__init__.py index c8103de49b..f98a4e86fc 100644 --- a/glance/registry/api/v1/__init__.py +++ b/glance/registry/api/v1/__init__.py @@ -45,13 +45,3 @@ class API(wsgi.Router): action="index_shared_images") super(API, self).__init__(mapper) - - -def app_factory(global_conf, **local_conf): - """ - paste.deploy app factory for creating Glance reference implementation - registry server apps - """ - conf = global_conf.copy() - conf.update(local_conf) - return API(conf) diff --git a/glance/registry/server.py b/glance/registry/server.py deleted file mode 100644 index 85201bd763..0000000000 --- a/glance/registry/server.py +++ /dev/null @@ -1,20 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010-2011 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# NOTE(bcwaldon): This is done as a convenience for people -# so they don't have to update their paste configs just yet. -from glance.registry.api.v1 import app_factory diff --git a/glance/store/scrubber.py b/glance/store/scrubber.py index 1e43ac1479..d6e5fc7cf0 100644 --- a/glance/store/scrubber.py +++ b/glance/store/scrubber.py @@ -180,9 +180,3 @@ def write_queue_file(file_path, uri, delete_time): f.write('\n'.join([uri, str(int(delete_time))])) os.chmod(file_path, 0600) os.utime(file_path, (delete_time, delete_time)) - - -def app_factory(global_config, **local_conf): - conf = global_config.copy() - conf.update(local_conf) - return Scrubber(conf) diff --git a/glance/tests/functional/__init__.py b/glance/tests/functional/__init__.py index b519e29848..8738e4abf2 100644 --- a/glance/tests/functional/__init__.py +++ b/glance/tests/functional/__init__.py @@ -217,19 +217,25 @@ image_cache_driver = %(image_cache_driver)s pipeline = versionnegotiation context %(cache_pipeline)s apiv1app [app:apiv1app] -paste.app_factory = glance.api.v1.router:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.api.v1.router:API [filter:versionnegotiation] -paste.filter_factory = glance.api.middleware.version_negotiation:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = + glance.api.middleware.version_negotiation:VersionNegotiationFilter [filter:cache] -paste.filter_factory = glance.api.middleware.cache:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.api.middleware.cache:CacheFilter [filter:cache_manage] -paste.filter_factory = glance.api.middleware.cache_manage:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter [filter:context] -paste.filter_factory = glance.common.context:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.common.context:ContextMiddleware """ @@ -267,11 +273,13 @@ owner_is_tenant = %(owner_is_tenant)s pipeline = context registryapp [app:registryapp] -paste.app_factory = glance.registry.api.v1:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.registry.api.v1:API [filter:context] context_class = glance.registry.context.RequestContext -paste.filter_factory = glance.common.context:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = glance.common.context:ContextMiddleware """ @@ -302,7 +310,8 @@ registry_host = 0.0.0.0 registry_port = %(registry_port)s [app:glance-scrubber] -paste.app_factory = glance.store.scrubber:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.store.scrubber:Scrubber """ diff --git a/glance/tests/functional/keystone_utils.py b/glance/tests/functional/keystone_utils.py index 2582c60a67..a58e49ac14 100644 --- a/glance/tests/functional/keystone_utils.py +++ b/glance/tests/functional/keystone_utils.py @@ -158,7 +158,9 @@ admin_token = 999888777666 delay_auth_decision = 1 [filter:keystone_shim] -paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory +paste.filter_factory = glance.common.wsgi:filter_factory +glance.filter_factory = + keystone.middleware.glance_auth_token:KeystoneContextMiddleware """ % subs diff --git a/glance/tests/functional/test_bin_glance_cache_manage.py b/glance/tests/functional/test_bin_glance_cache_manage.py index 6425dfc708..999f14e3ff 100644 --- a/glance/tests/functional/test_bin_glance_cache_manage.py +++ b/glance/tests/functional/test_bin_glance_cache_manage.py @@ -209,16 +209,20 @@ metadata_encryption_key = %(metadata_encryption_key)s log_file = %(log_file)s [app:glance-pruner] -paste.app_factory = glance.image_cache.pruner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.pruner:Pruner [app:glance-prefetcher] -paste.app_factory = glance.image_cache.prefetcher:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.prefetcher:Prefetcher [app:glance-cleaner] -paste.app_factory = glance.image_cache.cleaner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.cleaner:Cleaner [app:glance-queue-image] -paste.app_factory = glance.image_cache.queue_image:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.queue_image:Queuer """ % cache_file_options) cache_file.flush() diff --git a/glance/tests/functional/test_cache_middleware.py b/glance/tests/functional/test_cache_middleware.py index a02e6eb164..b06450e8ad 100644 --- a/glance/tests/functional/test_cache_middleware.py +++ b/glance/tests/functional/test_cache_middleware.py @@ -338,16 +338,20 @@ metadata_encryption_key = %(metadata_encryption_key)s log_file = %(log_file)s [app:glance-pruner] -paste.app_factory = glance.image_cache.pruner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.pruner:Pruner [app:glance-prefetcher] -paste.app_factory = glance.image_cache.prefetcher:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.prefetcher:Prefetcher [app:glance-cleaner] -paste.app_factory = glance.image_cache.cleaner:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.cleaner:Cleaner [app:glance-queue-image] -paste.app_factory = glance.image_cache.queue_image:app_factory +paste.app_factory = glance.common.wsgi:app_factory +glance.app_factory = glance.image_cache.queue_image:Queuer """ % cache_file_options) cache_file.flush() diff --git a/glance/tests/unit/test_config.py b/glance/tests/unit/test_config.py index 4d7d50b40b..1ebe250275 100644 --- a/glance/tests/unit/test_config.py +++ b/glance/tests/unit/test_config.py @@ -26,6 +26,7 @@ from glance.api.middleware import version_negotiation from glance.api.v1 import images from glance.api.v1 import members from glance.common import config +from glance.common import wsgi from glance.image_cache import pruner @@ -178,7 +179,7 @@ class TestPasteApp(unittest.TestCase): self.stubs.Set(os.path, 'join', fake_join) self.stubs.Set(config, 'setup_logging', lambda *a: None) - self.stubs.Set(pruner, 'app_factory', lambda *a: 'pruner') + self.stubs.Set(wsgi, 'app_factory', lambda *a, **kw: 'pruner') conf, app = config.load_paste_app('glance-pruner', {}, [], 'glance-cache')