Remove the conf passing PasteDeploy factories

Implements blueprint cfg-global-object

In glance.common.wsgi we have a paste_deploy_app() API which allows
a ConfigOpts instance to be passed the the applications and filters
constructed by PasteDeploy.

Now that we're using a global object, we don't need this anymore

Change-Id: I222d3c58308bc2f504cd802c0c8405d3baa2e49a
This commit is contained in:
Mark McLoughlin 2012-05-29 08:51:12 +01:00
parent 9d9d225419
commit d33ce445d3
28 changed files with 126 additions and 264 deletions

View File

@ -554,8 +554,7 @@ The cache middleware should be in your ``glance-api-paste.ini`` in a section
titled ``[filter:cache]``. It should look like this::
[filter:cache]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.cache:CacheFilter
paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory
A ready-made application pipeline including this filter is defined in
the ``glance-api-paste.ini`` file, looking like so::

View File

@ -44,32 +44,25 @@ use = egg:Paste#urlmap
paste.app_factory = glance.api.versions:create_resource
[app:apiv1app]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.api.v1.router:API
paste.app_factory = glance.api.v1.router:API.factory
[app:apiv2app]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.api.v2.router:API
paste.app_factory = glance.api.v2.router:API.factory
[filter:versionnegotiation]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter
paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory
[filter:cache]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.cache:CacheFilter
paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory
[filter:cachemanage]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter
paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory
[filter:context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:ContextMiddleware
paste.filter_factory = glance.common.context:ContextMiddleware.factory
[filter:unauthenticated-context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:UnauthenticatedContextMiddleware
paste.filter_factory = glance.common.context:UnauthenticatedContextMiddleware.factory
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory

View File

@ -1,15 +1,11 @@
[app:glance-pruner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.pruner:Pruner
paste.app_factory = glance.image_cache.pruner:Pruner.factory
[app:glance-prefetcher]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.prefetcher:Prefetcher
paste.app_factory = glance.image_cache.prefetcher:Prefetcher.factory
[app:glance-cleaner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.cleaner:Cleaner
paste.app_factory = glance.image_cache.cleaner:Cleaner.factory
[app:glance-queue-image]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.queue_image:Queuer
paste.app_factory = glance.image_cache.queue_image:Queuer.factory

View File

@ -11,16 +11,13 @@ pipeline = unauthenticated-context registryapp
pipeline = authtoken context registryapp
[app:registryapp]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.registry.api.v1:API
paste.app_factory = glance.registry.api.v1:API.factory
[filter:context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:ContextMiddleware
paste.filter_factory = glance.common.context:ContextMiddleware.factory
[filter:unauthenticated-context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:UnauthenticatedContextMiddleware
paste.filter_factory = glance.common.context:UnauthenticatedContextMiddleware.factory
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory

View File

@ -1,3 +1,2 @@
[app:glance-scrubber]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.store.scrubber:Scrubber
paste.app_factory = glance.store.scrubber:Scrubber.factory

View File

@ -43,7 +43,7 @@ get_images_re = re.compile(r'^(/v\d+)*/images/([^\/]+)$')
class CacheFilter(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
self.cache = image_cache.ImageCache()
self.serializer = images.ImageSerializer()
logger.info(_("Initialized image cache middleware"))

View File

@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
class CacheManageFilter(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
mapper = routes.Mapper()
resource = cached_images.create_resource()

View File

@ -31,7 +31,7 @@ logger = logging.getLogger('glance.api.middleware.version_negotiation')
class VersionNegotiationFilter(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
self.versions_app = versions.Controller()
super(VersionNegotiationFilter, self).__init__(app)

View File

@ -30,9 +30,7 @@ class API(wsgi.Router):
"""WSGI router for Glance v1 API requests."""
def __init__(self, conf, **local_conf):
mapper = routes.Mapper()
def __init__(self, mapper):
images_resource = images.create_resource()
mapper.resource("image", "images", controller=images_resource,

View File

@ -35,9 +35,7 @@ class API(wsgi.Router):
"""WSGI router for Glance v2 API requests."""
def __init__(self, conf, **local_conf):
mapper = routes.Mapper()
def __init__(self, mapper):
schema_api = glance.schema.API()
glance.schema.load_custom_schema_properties(schema_api)

View File

@ -26,7 +26,8 @@ import logging.handlers
import os
import sys
from glance.common import wsgi
from paste import deploy
from glance.openstack.common import cfg
from glance import version
@ -169,7 +170,7 @@ def load_paste_app(app_name=None, default_paste_file=None):
logger.debug(_("Loading %(app_name)s from %(conf_file)s"),
{'conf_file': conf_file, 'app_name': app_name})
app = wsgi.paste_deploy_app(conf_file, app_name, CONF)
app = deploy.loadapp("config:%s" % conf_file, name=app_name)
# Log the options used when starting if we're in debug mode...
if CONF.debug:

View File

@ -138,7 +138,7 @@ class RequestContext(object):
class ContextMiddleware(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
super(ContextMiddleware, self).__init__(app)
def process_request(self, req):
@ -193,7 +193,7 @@ class ContextMiddleware(wsgi.Middleware):
class UnauthenticatedContextMiddleware(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
super(UnauthenticatedContextMiddleware, self).__init__(app)
def process_request(self, req):

View File

@ -34,7 +34,6 @@ import eventlet
import eventlet.greenio
from eventlet.green import socket, ssl
import eventlet.wsgi
from paste import deploy
import routes
import routes.middleware
import webob.dec
@ -43,7 +42,6 @@ import webob.exc
from glance.common import exception
from glance.common import utils
from glance.openstack.common import cfg
from glance.openstack.common import importutils
bind_opts = [
@ -273,6 +271,12 @@ class Middleware(object):
def __init__(self, application):
self.application = application
@classmethod
def factory(cls, global_conf, **local_conf):
def filter(app):
return cls(app)
return filter
def process_request(self, req):
"""
Called on each request.
@ -367,6 +371,10 @@ class Router(object):
self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map)
@classmethod
def factory(cls, global_conf, **local_conf):
return cls(routes.Mapper())
@webob.dec.wsgify
def __call__(self, req):
"""
@ -528,139 +536,3 @@ class Resource(object):
pass
return args
class BasePasteFactory(object):
"""A base class for paste app and filter factories.
Sub-classes must override the KEY class attribute and provide
a __call__ method.
"""
KEY = None
def __init__(self, conf):
self.conf = conf
def __call__(self, global_conf, **local_conf):
raise NotImplementedError
def _import_factory(self, local_conf):
"""Import an app/filter class.
Lookup the KEY from the PasteDeploy local conf and import the
class named therein. This class can then be used as an app or
filter factory.
Note we support the <module>:<class> format.
Note also that if you do e.g.
key =
value
then ConfigParser returns a value with a leading newline, so
we strip() the value before using it.
"""
class_name = local_conf[self.KEY].replace(':', '.').strip()
return importutils.import_class(class_name)
class AppFactory(BasePasteFactory):
"""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 <module>:<callable> 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 ConfigOpts object and a local config
dict as its two arguments.
"""
KEY = 'glance.app_factory'
def __call__(self, global_conf, **local_conf):
"""The actual paste.app_factory protocol method."""
factory = self._import_factory(local_conf)
return factory(self.conf, **local_conf)
class FilterFactory(AppFactory):
"""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 <module>:<callable> 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, a ConfigOpts object and
a local config dict as its three arguments.
"""
KEY = 'glance.filter_factory'
def __call__(self, global_conf, **local_conf):
"""The actual paste.filter_factory protocol method."""
factory = self._import_factory(local_conf)
def filter(app):
return factory(app, self.conf, **local_conf)
return filter
def setup_paste_factories(conf):
"""Set up the generic paste app and filter factories.
Set things up so that:
paste.app_factory = glance.common.wsgi:app_factory
and
paste.filter_factory = glance.common.wsgi:filter_factory
work correctly while loading PasteDeploy configuration.
The app factories are constructed at runtime to allow us to pass a
ConfigOpts object to the WSGI classes.
:param conf: a ConfigOpts object
"""
global app_factory, filter_factory
app_factory = AppFactory(conf)
filter_factory = FilterFactory(conf)
def teardown_paste_factories():
"""Reverse the effect of setup_paste_factories()."""
global app_factory, filter_factory
del app_factory
del filter_factory
def paste_deploy_app(paste_config_file, app_name, conf):
"""Load a WSGI app from a PasteDeploy configuration.
Use deploy.loadapp() to load the app from the PasteDeploy configuration,
ensuring that the supplied ConfigOpts object is passed to the app and
filter constructors.
:param paste_config_file: a PasteDeploy config file
:param app_name: the name of the app/pipeline to load from the file
:param conf: a ConfigOpts object to supply to the app and its filters
:returns: the WSGI app
"""
setup_paste_factories(conf)
try:
return deploy.loadapp("config:%s" % paste_config_file, name=app_name)
finally:
teardown_paste_factories()

View File

@ -0,0 +1,27 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Red Hat, Inc.
#
# 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.
from glance.image_cache import ImageCache
class CacheApp(object):
def __init__(self):
self.cache = ImageCache()
@classmethod
def factory(cls, global_conf, **local_conf):
return cls()

View File

@ -15,20 +15,15 @@
# License for the specific language governing permissions and limitations
# under the License.
"""
Cleans up any invalid cache entries
"""
import logging
from glance.image_cache import ImageCache
logger = logging.getLogger(__name__)
from glance.image_cache import base
class Cleaner(object):
def __init__(self, conf, **local_conf):
self.cache = ImageCache()
class Cleaner(base.CacheApp):
def run(self):
self.cache.clean()

View File

@ -25,7 +25,7 @@ import eventlet
from glance.common import context
from glance.common import exception
from glance.image_cache import ImageCache
from glance.image_cache import base
from glance import registry
import glance.store
import glance.store.filesystem
@ -39,11 +39,11 @@ from glance.store import get_from_backend
logger = logging.getLogger(__name__)
class Prefetcher(object):
class Prefetcher(base.CacheApp):
def __init__(self, conf, **local_conf):
def __init__(self):
glance.store.create_stores()
self.cache = ImageCache()
super(Prefetcher, self).__init__()
registry.configure_registry_client()
registry.configure_registry_admin_creds()

View File

@ -21,14 +21,12 @@ Prunes the Image Cache
import logging
from glance.image_cache import ImageCache
from glance.image_cache import base
logger = logging.getLogger(__name__)
class Pruner(object):
def __init__(self, conf, **local_conf):
self.cache = ImageCache()
class Pruner(base.CacheApp):
def run(self):
self.cache.prune()

View File

@ -25,17 +25,17 @@ import eventlet
from glance.common import context
from glance.common import exception
from glance.image_cache import ImageCache
from glance.image_cache import base
from glance import registry
logger = logging.getLogger(__name__)
class Queuer(object):
class Queuer(base.CacheApp):
def __init__(self, conf, **local_conf):
self.cache = ImageCache()
def __init__(self):
super(Queuer, self).__init__()
registry.configure_registry_client()
registry.configure_registry_admin_creds()

View File

@ -25,7 +25,7 @@ from glance.registry.api.v1 import members
class API(wsgi.Router):
"""WSGI entry point for all Registry requests."""
def __init__(self, conf, **local_conf):
def __init__(self, mapper):
mapper = routes.Mapper()
images_resource = images.create_resource()

View File

@ -70,7 +70,7 @@ class Daemon(object):
class Scrubber(object):
CLEANUP_FILE = ".cleanup"
def __init__(self, conf, **local_conf):
def __init__(self):
self.datadir = CONF.scrubber_datadir
self.cleanup = CONF.cleanup_scrubber
self.cleanup_time = CONF.cleanup_scrubber_time
@ -88,6 +88,10 @@ class Scrubber(object):
store.create_stores()
@classmethod
def factory(cls, global_conf, **local_conf):
return cls()
def run(self, pool, event=None):
now = time.time()

View File

@ -289,37 +289,31 @@ use = egg:Paste#urlmap
paste.app_factory = glance.api.versions:create_resource
[app:apiv1app]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.api.v1.router:API
paste.app_factory = glance.api.v1.router:API.factory
[app:apiv2app]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.api.v2.router:API
paste.app_factory = glance.api.v2.router:API.factory
[filter:versionnegotiation]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory =
glance.api.middleware.version_negotiation:VersionNegotiationFilter
paste.filter_factory =
glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory
[filter:cache]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.cache:CacheFilter
paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory
[filter:cache_manage]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter
paste.filter_factory =
glance.api.middleware.cache_manage:CacheManageFilter.factory
[filter:context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:ContextMiddleware
paste.filter_factory = glance.common.context:ContextMiddleware.factory
[filter:unauthenticated-context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:UnauthenticatedContextMiddleware
paste.filter_factory =
glance.common.context:UnauthenticatedContextMiddleware.factory
[filter:fakeauth]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.tests.utils:FakeAuthMiddleware
paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory
"""
@ -365,20 +359,17 @@ pipeline = unauthenticated-context registryapp
pipeline = fakeauth context registryapp
[app:registryapp]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.registry.api.v1:API
paste.app_factory = glance.registry.api.v1:API.factory
[filter:context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:ContextMiddleware
paste.filter_factory = glance.common.context:ContextMiddleware.factory
[filter:unauthenticated-context]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.common.context:UnauthenticatedContextMiddleware
paste.filter_factory =
glance.common.context:UnauthenticatedContextMiddleware.factory
[filter:fakeauth]
paste.filter_factory = glance.common.wsgi:filter_factory
glance.filter_factory = glance.tests.utils:FakeAuthMiddleware
paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory
"""
@ -409,8 +400,7 @@ registry_host = 0.0.0.0
registry_port = %(registry_port)s
"""
self.paste_conf_base = """[app:glance-scrubber]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.store.scrubber:Scrubber
paste.app_factory = glance.store.scrubber:Scrubber.factory
"""

View File

@ -209,20 +209,16 @@ log_file = %(log_file)s
with open(cache_config_filepath.replace(".conf", "-paste.ini"),
'w') as paste_file:
paste_file.write("""[app:glance-pruner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.pruner:Pruner
paste.app_factory = glance.image_cache.pruner:Pruner.factory
[app:glance-prefetcher]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.prefetcher:Prefetcher
paste.app_factory = glance.image_cache.prefetcher:Prefetcher.factory
[app:glance-cleaner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.cleaner:Cleaner
paste.app_factory = glance.image_cache.cleaner:Cleaner.factory
[app:glance-queue-image]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.queue_image:Queuer
paste.app_factory = glance.image_cache.queue_image:Queuer.factory
""")
cmd = ("bin/glance-cache-prefetcher --config-file %s" %

View File

@ -460,20 +460,16 @@ log_file = %(log_file)s
with open(cache_config_filepath.replace(".conf", "-paste.ini"),
'w') as paste_file:
paste_file.write("""[app:glance-pruner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.pruner:Pruner
paste.app_factory = glance.image_cache.pruner:Pruner.factory
[app:glance-prefetcher]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.prefetcher:Prefetcher
paste.app_factory = glance.image_cache.prefetcher:Prefetcher.factory
[app:glance-cleaner]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.cleaner:Cleaner
paste.app_factory = glance.image_cache.cleaner:Cleaner.factory
[app:glance-queue-image]
paste.app_factory = glance.common.wsgi:app_factory
glance.app_factory = glance.image_cache.queue_image:Queuer
paste.app_factory = glance.image_cache.queue_image:Queuer.factory
""")
self.verify_no_images()

View File

@ -25,6 +25,7 @@ try:
except ImportError:
SENDFILE_SUPPORTED = False
import routes
import webob
from glance.api.v1 import router
@ -65,8 +66,8 @@ def stub_out_registry_and_store_server(stubs, base_dir):
self.req.body = body
def getresponse(self):
api = context.UnauthenticatedContextMiddleware(rserver.API(None),
None)
mapper = routes.Mapper()
api = context.UnauthenticatedContextMiddleware(rserver.API(mapper))
res = self.req.get_response(api)
# httplib.Response has a read() method...fake it out
@ -143,8 +144,8 @@ def stub_out_registry_and_store_server(stubs, base_dir):
self.req.body = body
def getresponse(self):
api = context.UnauthenticatedContextMiddleware(router.API(None),
None)
mapper = routes.Mapper()
api = context.UnauthenticatedContextMiddleware(router.API(mapper))
res = self.req.get_response(api)
# httplib.Response has a read() method...fake it out
@ -218,8 +219,8 @@ def stub_out_registry_server(stubs, **kwargs):
self.req.body = body
def getresponse(self):
api = context.UnauthenticatedContextMiddleware(rserver.API(None),
None)
mapper = routes.Mapper()
api = context.UnauthenticatedContextMiddleware(rserver.API(mapper))
res = self.req.get_response(api)
# httplib.Response has a read() method...fake it out

View File

@ -112,8 +112,8 @@ class TestPasteApp(test_utils.BaseTestCase):
config.parse_cache_args([])
self.stubs.Set(config, 'setup_logging', lambda *a: None)
self.stubs.Set(pruner, 'Pruner', lambda conf, **lc: 'pruner')
self.stubs.Set(pruner.Pruner, '__init__', lambda p: None)
app = config.load_paste_app('glance-pruner')
self.assertEquals('pruner', app)
self.assertTrue(isinstance(app, pruner.Pruner))

View File

@ -18,7 +18,7 @@ class TestContextMiddleware(base.IsolatedUnitTest):
return req
def _build_middleware(self):
return context.ContextMiddleware(None, None)
return context.ContextMiddleware(None)
def test_header_parsing(self):
req = self._build_request()
@ -66,7 +66,7 @@ class TestContextMiddleware(base.IsolatedUnitTest):
class TestUnauthenticatedContextMiddleware(base.IsolatedUnitTest):
def test_request(self):
middleware = context.UnauthenticatedContextMiddleware(None, None)
middleware = context.UnauthenticatedContextMiddleware(None)
req = webob.Request.blank('/')
middleware.process_request(req)
self.assertEqual(req.context.auth_tok, None)

View File

@ -20,6 +20,7 @@ import hashlib
import httplib
import json
import routes
import stubout
import webob
@ -72,7 +73,7 @@ class TestRegistryDb(test_utils.BaseTestCase):
self.stubs.Set(db_api.logger, 'error', fake_log_error)
try:
api_obj = rserver.API(None)
api_obj = rserver.API(routes.Mapper())
except exc.ArgumentError:
exc_raised = True
except ImportError:
@ -92,8 +93,9 @@ class TestRegistryAPI(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""
super(TestRegistryAPI, self).setUp()
self.api = context.UnauthenticatedContextMiddleware(rserver.API(None),
None)
mapper = routes.Mapper()
self.api = (
context.UnauthenticatedContextMiddleware(rserver.API(mapper)))
self.FIXTURES = [
{'id': UUID1,
'name': 'fake image #1',
@ -1961,8 +1963,8 @@ class TestGlanceAPI(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""
super(TestGlanceAPI, self).setUp()
self.api = context.UnauthenticatedContextMiddleware(router.API(None),
None)
mapper = routes.Mapper()
self.api = context.UnauthenticatedContextMiddleware(router.API(mapper))
self.FIXTURES = [
{'id': UUID1,
'name': 'fake image #1',

View File

@ -351,7 +351,7 @@ def minimal_add_command(port, name, suffix='', public=True):
class FakeAuthMiddleware(wsgi.Middleware):
def __init__(self, app, conf, **local_conf):
def __init__(self, app):
super(FakeAuthMiddleware, self).__init__(app)
def process_request(self, req):