Work in progress on network API
This commit is contained in:
parent
702e64fc52
commit
3a421e759f
17
bin/quantum
17
bin/quantum
@ -35,6 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'quantum', '__init__.py')):
|
||||
|
||||
gettext.install('quantum', unicode=1)
|
||||
|
||||
from quantum import service
|
||||
from quantum.common import wsgi
|
||||
from quantum.common import config
|
||||
|
||||
@ -54,10 +55,18 @@ if __name__ == '__main__':
|
||||
(options, args) = config.parse_options(oparser)
|
||||
|
||||
try:
|
||||
conf, app = config.load_paste_app('quantumversionapp', options, args)
|
||||
server = wsgi.Server()
|
||||
server.start(app, int(conf['bind_port']), conf['bind_host'])
|
||||
server.wait()
|
||||
print "HERE-1"
|
||||
service = service.serve_wsgi(service.QuantumApiService,
|
||||
options=options,
|
||||
args=args)
|
||||
#version_conf, version_app = config.load_paste_app('quantumversion', options, args)
|
||||
print "HERE-2"
|
||||
service.wait()
|
||||
#api_conf, api_app = config.load_paste_app('quantum', options, args)
|
||||
#server = wsgi.Server()
|
||||
#server.start(version_app, int(version_conf['bind_port']), version_conf['bind_host'])
|
||||
#server.start(api_app, int(api_conf['bind_port']), api_conf['bind_host'])
|
||||
#server.wait()
|
||||
except RuntimeError, e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
|
||||
|
@ -11,9 +11,15 @@ bind_host = 0.0.0.0
|
||||
# Port the bind the API server to
|
||||
bind_port = 9696
|
||||
|
||||
#[app:quantum]
|
||||
#paste.app_factory = quantum.service:app_factory
|
||||
[composite:quantum]
|
||||
use = egg:Paste#urlmap
|
||||
/: quantumversions
|
||||
/v0.1: quantumapi
|
||||
|
||||
[app:quantumversionapp]
|
||||
[app:quantumversions]
|
||||
paste.app_factory = quantum.api.versions:Versions.factory
|
||||
|
||||
[app:quantumapi]
|
||||
paste.app_factory = quantum.api:APIRouterV01.factory
|
||||
|
||||
|
||||
|
@ -13,4 +13,69 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# @author: Somik Behera, Nicira Networks, Inc.
|
||||
# @author: Salvatore Orlando, Citrix Systems
|
||||
|
||||
"""
|
||||
Quantum API controllers.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import routes
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
|
||||
from quantum.api import faults
|
||||
from quantum.api import networks
|
||||
from quantum.common import flags
|
||||
from quantum.common import wsgi
|
||||
|
||||
|
||||
LOG = logging.getLogger('quantum.api')
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
class FaultWrapper(wsgi.Middleware):
|
||||
"""Calls down the middleware stack, making exceptions into faults."""
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
try:
|
||||
return req.get_response(self.application)
|
||||
except Exception as ex:
|
||||
LOG.exception(_("Caught error: %s"), unicode(ex))
|
||||
exc = webob.exc.HTTPInternalServerError(explanation=unicode(ex))
|
||||
return faults.Fault(exc)
|
||||
|
||||
|
||||
class APIRouterV01(wsgi.Router):
|
||||
"""
|
||||
Routes requests on the Quantum API to the appropriate controller
|
||||
"""
|
||||
|
||||
def __init__(self, ext_mgr=None):
|
||||
mapper = routes.Mapper()
|
||||
self._setup_routes(mapper)
|
||||
super(APIRouterV01, self).__init__(mapper)
|
||||
|
||||
def _setup_routes(self, mapper):
|
||||
#server_members = self.server_members
|
||||
#server_members['action'] = 'POST'
|
||||
|
||||
#server_members['pause'] = 'POST'
|
||||
#server_members['unpause'] = 'POST'
|
||||
#server_members['diagnostics'] = 'GET'
|
||||
#server_members['actions'] = 'GET'
|
||||
#server_members['suspend'] = 'POST'
|
||||
#server_members['resume'] = 'POST'
|
||||
#server_members['rescue'] = 'POST'
|
||||
#server_members['unrescue'] = 'POST'
|
||||
#server_members['reset_network'] = 'POST'
|
||||
#server_members['inject_network_info'] = 'POST'
|
||||
|
||||
mapper.resource("network", "networks", controller=networks.Controller(),
|
||||
collection={'detail': 'GET'})
|
||||
print mapper
|
||||
#mapper.resource("port", "ports", controller=ports.Controller(),
|
||||
# collection=dict(public='GET', private='GET'),
|
||||
# parent_resource=dict(member_name='network',
|
||||
# collection_name='networks'))
|
||||
|
||||
|
21
quantum/api/api_common.py
Normal file
21
quantum/api/api_common.py
Normal file
@ -0,0 +1,21 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 Citrix System.
|
||||
# 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.
|
||||
|
||||
|
||||
XML_NS_V01 = 'http://netstack.org/quantum/api/v0.1'
|
||||
XML_NS_V10 = 'http://netstack.org/quantum/api/v1.0'
|
||||
|
62
quantum/api/faults.py
Normal file
62
quantum/api/faults.py
Normal file
@ -0,0 +1,62 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 Citrix Systems.
|
||||
# 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.
|
||||
|
||||
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import wsgi
|
||||
|
||||
class Fault(webob.exc.HTTPException):
|
||||
"""Error codes for API faults"""
|
||||
|
||||
_fault_names = {
|
||||
400: "malformedRequest",
|
||||
401: "unauthorized",
|
||||
402: "networkNotFound",
|
||||
403: "requestedStateInvalid",
|
||||
460: "networkInUse",
|
||||
461: "alreadyAttached",
|
||||
462: "portInUse",
|
||||
470: "serviceUnavailable",
|
||||
471: "pluginFault"
|
||||
}
|
||||
|
||||
def __init__(self, exception):
|
||||
"""Create a Fault for the given webob.exc.exception."""
|
||||
self.wrapped_exc = exception
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
"""Generate a WSGI response based on the exception passed to ctor."""
|
||||
# Replace the body with fault details.
|
||||
code = self.wrapped_exc.status_int
|
||||
fault_name = self._fault_names.get(code, "quantumServiceFault")
|
||||
fault_data = {
|
||||
fault_name: {
|
||||
'code': code,
|
||||
'message': self.wrapped_exc.explanation}}
|
||||
#TODO (salvatore-orlando): place over-limit stuff here
|
||||
# 'code' is an attribute on the fault tag itself
|
||||
metadata = {'application/xml': {'attributes': {fault_name: 'code'}}}
|
||||
default_xmlns = common.XML_NS_V10
|
||||
serializer = wsgi.Serializer(metadata, default_xmlns)
|
||||
content_type = req.best_match_content_type()
|
||||
self.wrapped_exc.body = serializer.serialize(fault_data, content_type)
|
||||
self.wrapped_exc.content_type = content_type
|
||||
return self.wrapped_exc
|
200
quantum/api/networks.py
Normal file
200
quantum/api/networks.py
Normal file
@ -0,0 +1,200 @@
|
||||
# Copyright 2011 Citrix Systems.
|
||||
# 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.
|
||||
|
||||
import base64
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from webob import exc
|
||||
from xml.dom import minidom
|
||||
|
||||
from quantum import manager
|
||||
from quantum import quantum_plugin_base
|
||||
from quantum.common import exceptions as exception
|
||||
from quantum.common import flags
|
||||
from quantum.common import wsgi
|
||||
from quantum import utils
|
||||
from quantum.api import api_common as common
|
||||
from quantum.api import faults
|
||||
import quantum.api
|
||||
|
||||
LOG = logging.getLogger('quantum.api.networks')
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class Controller(wsgi.Controller):
|
||||
""" Network API controller for Quantum API """
|
||||
|
||||
#TODO (salvatore-orlando): adjust metadata for quantum
|
||||
_serialization_metadata = {
|
||||
"application/xml": {
|
||||
"attributes": {
|
||||
"server": ["id", "imageId", "name", "flavorId", "hostId",
|
||||
"status", "progress", "adminPass", "flavorRef",
|
||||
"imageRef"],
|
||||
"link": ["rel", "type", "href"],
|
||||
},
|
||||
"dict_collections": {
|
||||
"metadata": {"item_name": "meta", "item_key": "key"},
|
||||
},
|
||||
"list_collections": {
|
||||
"public": {"item_name": "ip", "item_key": "addr"},
|
||||
"private": {"item_name": "ip", "item_key": "addr"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def index(self, request):
|
||||
""" Returns a list of network names and ids """
|
||||
#TODO: this should be for a given tenant!!!
|
||||
print "PIPPO"
|
||||
LOG.debug("HERE - index")
|
||||
return self._items(request, is_detail=False)
|
||||
|
||||
def _items(self, req, is_detail):
|
||||
""" Returns a list of networks. """
|
||||
#TODO: we should return networks for a given tenant only
|
||||
#TODO: network controller should be retrieved here!!!
|
||||
test = { 'ciao':'bello','porco':'mondo' }
|
||||
#builder = self._get_view_builder(req)
|
||||
#servers = [builder.build(inst, is_detail)['server']
|
||||
# for inst in limited_list]
|
||||
#return dict(servers=servers)
|
||||
return test
|
||||
|
||||
def show(self, req, id):
|
||||
""" Returns network details by network id """
|
||||
try:
|
||||
return "TEST NETWORK DETAILS"
|
||||
except exception.NotFound:
|
||||
return faults.Fault(exc.HTTPNotFound())
|
||||
|
||||
def delete(self, req, id):
|
||||
""" Destroys the network with the given id """
|
||||
try:
|
||||
return "TEST NETWORK DELETE"
|
||||
except exception.NotFound:
|
||||
return faults.Fault(exc.HTTPNotFound())
|
||||
return exc.HTTPAccepted()
|
||||
|
||||
def create(self, req):
|
||||
""" Creates a new network for a given tenant """
|
||||
#env = self._deserialize_create(req)
|
||||
#if not env:
|
||||
# return faults.Fault(exc.HTTPUnprocessableEntity())
|
||||
return "TEST NETWORK CREATE"
|
||||
|
||||
def _deserialize_create(self, request):
|
||||
"""
|
||||
Deserialize a create request
|
||||
Overrides normal behavior in the case of xml content
|
||||
"""
|
||||
#if request.content_type == "application/xml":
|
||||
# deserializer = ServerCreateRequestXMLDeserializer()
|
||||
# return deserializer.deserialize(request.body)
|
||||
#else:
|
||||
# return self._deserialize(request.body, request.get_content_type())
|
||||
pass
|
||||
|
||||
def update(self, req, id):
|
||||
""" Updates the name for the network wit the given id """
|
||||
if len(req.body) == 0:
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
inst_dict = self._deserialize(req.body, req.get_content_type())
|
||||
if not inst_dict:
|
||||
return faults.Fault(exc.HTTPUnprocessableEntity())
|
||||
|
||||
try:
|
||||
return "TEST NETWORK UPDATE"
|
||||
except exception.NotFound:
|
||||
return faults.Fault(exc.HTTPNotFound())
|
||||
return exc.HTTPNoContent()
|
||||
|
||||
|
||||
class NetworkCreateRequestXMLDeserializer(object):
|
||||
"""
|
||||
Deserializer to handle xml-formatted server create requests.
|
||||
|
||||
Handles standard server attributes as well as optional metadata
|
||||
and personality attributes
|
||||
"""
|
||||
|
||||
def deserialize(self, string):
|
||||
"""Deserialize an xml-formatted server create request"""
|
||||
dom = minidom.parseString(string)
|
||||
server = self._extract_server(dom)
|
||||
return {'server': server}
|
||||
|
||||
def _extract_server(self, node):
|
||||
"""Marshal the server attribute of a parsed request"""
|
||||
server = {}
|
||||
server_node = self._find_first_child_named(node, 'server')
|
||||
for attr in ["name", "imageId", "flavorId"]:
|
||||
server[attr] = server_node.getAttribute(attr)
|
||||
metadata = self._extract_metadata(server_node)
|
||||
if metadata is not None:
|
||||
server["metadata"] = metadata
|
||||
personality = self._extract_personality(server_node)
|
||||
if personality is not None:
|
||||
server["personality"] = personality
|
||||
return server
|
||||
|
||||
def _extract_metadata(self, server_node):
|
||||
"""Marshal the metadata attribute of a parsed request"""
|
||||
metadata_node = self._find_first_child_named(server_node, "metadata")
|
||||
if metadata_node is None:
|
||||
return None
|
||||
metadata = {}
|
||||
for meta_node in self._find_children_named(metadata_node, "meta"):
|
||||
key = meta_node.getAttribute("key")
|
||||
metadata[key] = self._extract_text(meta_node)
|
||||
return metadata
|
||||
|
||||
def _extract_personality(self, server_node):
|
||||
"""Marshal the personality attribute of a parsed request"""
|
||||
personality_node = \
|
||||
self._find_first_child_named(server_node, "personality")
|
||||
if personality_node is None:
|
||||
return None
|
||||
personality = []
|
||||
for file_node in self._find_children_named(personality_node, "file"):
|
||||
item = {}
|
||||
if file_node.hasAttribute("path"):
|
||||
item["path"] = file_node.getAttribute("path")
|
||||
item["contents"] = self._extract_text(file_node)
|
||||
personality.append(item)
|
||||
return personality
|
||||
|
||||
def _find_first_child_named(self, parent, name):
|
||||
"""Search a nodes children for the first child with a given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
return node
|
||||
return None
|
||||
|
||||
def _find_children_named(self, parent, name):
|
||||
"""Return all of a nodes children who have the given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
yield node
|
||||
|
||||
def _extract_text(self, node):
|
||||
"""Get the text field contained by the given node"""
|
||||
if len(node.childNodes) == 1:
|
||||
child = node.childNodes[0]
|
||||
if child.nodeType == child.TEXT_NODE:
|
||||
return child.nodeValue
|
||||
return ""
|
@ -244,10 +244,12 @@ def load_paste_config(app_name, options, args):
|
||||
problem loading the configuration file.
|
||||
"""
|
||||
conf_file = find_config_file(options, args)
|
||||
print "Conf_file:%s" %conf_file
|
||||
if not conf_file:
|
||||
raise RuntimeError("Unable to locate any configuration file. "
|
||||
"Cannot load application %s" % app_name)
|
||||
try:
|
||||
print "App_name:%s" %app_name
|
||||
conf = deploy.appconfig("config:%s" % conf_file, name=app_name)
|
||||
return conf_file, conf
|
||||
except Exception, e:
|
||||
@ -255,7 +257,7 @@ def load_paste_config(app_name, options, args):
|
||||
% (conf_file, e))
|
||||
|
||||
|
||||
def load_paste_app(app_name, options, args):
|
||||
def load_paste_app(conf_file, app_name):
|
||||
"""
|
||||
Builds and returns a WSGI app from a paste config file.
|
||||
|
||||
@ -276,40 +278,16 @@ def load_paste_app(app_name, options, args):
|
||||
:raises RuntimeError when config file cannot be located or application
|
||||
cannot be loaded from config file
|
||||
"""
|
||||
conf_file, conf = load_paste_config(app_name, options, args)
|
||||
#conf_file, conf = load_paste_config(app_name, options, args)
|
||||
|
||||
try:
|
||||
# Setup logging early, supplying both the CLI options and the
|
||||
# configuration mapping from the config file
|
||||
print "OPTIONS:%s" %options
|
||||
print "CONF:%s" %conf
|
||||
setup_logging(options, conf)
|
||||
|
||||
# We only update the conf dict for the verbose and debug
|
||||
# flags. Everything else must be set up in the conf file...
|
||||
debug = options.get('debug') or \
|
||||
get_option(conf, 'debug', type='bool', default=False)
|
||||
verbose = options.get('verbose') or \
|
||||
get_option(conf, 'verbose', type='bool', default=False)
|
||||
conf['debug'] = debug
|
||||
conf['verbose'] = verbose
|
||||
|
||||
# Log the options used when starting if we're in debug mode...
|
||||
LOG.debug("*" * 80)
|
||||
LOG.debug("Configuration options gathered from config file:")
|
||||
LOG.debug(conf_file)
|
||||
LOG.debug("================================================")
|
||||
items = dict([(k, v) for k, v in conf.items()
|
||||
if k not in ('__file__', 'here')])
|
||||
for key, value in sorted(items.items()):
|
||||
LOG.debug("%(key)-30s %(value)s" % locals())
|
||||
LOG.debug("*" * 80)
|
||||
conf_file = os.path.abspath(conf_file)
|
||||
app = deploy.loadapp("config:%s" % conf_file, name=app_name)
|
||||
except (LookupError, ImportError), e:
|
||||
raise RuntimeError("Unable to load %(app_name)s from "
|
||||
"configuration file %(conf_file)s."
|
||||
"\nGot: %(e)r" % locals())
|
||||
return conf, app
|
||||
return app
|
||||
|
||||
|
||||
def get_option(options, option, **kwargs):
|
||||
|
@ -29,7 +29,7 @@ import socket
|
||||
import sys
|
||||
import ConfigParser
|
||||
|
||||
from common import exceptions
|
||||
from quantum.common import exceptions
|
||||
from exceptions import ProcessExecutionError
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2011, Nicira Networks, Inc.
|
||||
@ -253,6 +254,13 @@ class Router(object):
|
||||
WSGI middleware that maps incoming requests to WSGI apps.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def factory(cls, global_config, **local_config):
|
||||
"""
|
||||
Returns an instance of the WSGI Router class
|
||||
"""
|
||||
return cls()
|
||||
|
||||
def __init__(self, mapper):
|
||||
"""
|
||||
Create a router for the given routes.Mapper.
|
||||
@ -337,7 +345,7 @@ class Controller(object):
|
||||
MIME types to information needed to serialize to that type.
|
||||
"""
|
||||
_metadata = getattr(type(self), "_serialization_metadata", {})
|
||||
serializer = Serializer(request.environ, _metadata)
|
||||
serializer = Serializer(_metadata)
|
||||
return serializer.to_content_type(data)
|
||||
|
||||
|
||||
|
@ -15,30 +15,104 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import json
|
||||
import routes
|
||||
from common import wsgi
|
||||
from quantum.common import config
|
||||
from quantum.common import wsgi
|
||||
from quantum.common import exceptions as exception
|
||||
from webob import Response
|
||||
|
||||
LOG = logging.getLogger('quantum.service')
|
||||
|
||||
class NetworkController(wsgi.Controller):
|
||||
class WsgiService(object):
|
||||
"""Base class for WSGI based services.
|
||||
|
||||
def version(self, request):
|
||||
return "Quantum version 0.1"
|
||||
For each api you define, you must also define these flags:
|
||||
:<api>_listen: The address on which to listen
|
||||
:<api>_listen_port: The port on which to listen
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, app_name, conf_file, conf):
|
||||
self.app_name = app_name
|
||||
self.conf_file = conf_file
|
||||
self.conf = conf
|
||||
self.wsgi_app = None
|
||||
|
||||
def start(self):
|
||||
self.wsgi_app = _run_wsgi(self.app_name, self.conf, self.conf_file)
|
||||
|
||||
def wait(self):
|
||||
self.wsgi_app.wait()
|
||||
|
||||
|
||||
class API(wsgi.Router):
|
||||
def __init__(self, options):
|
||||
self.options = options
|
||||
mapper = routes.Mapper()
|
||||
network_controller = NetworkController()
|
||||
mapper.resource("net_controller", "/network",
|
||||
controller=network_controller)
|
||||
mapper.connect("/", controller=network_controller, action="version")
|
||||
super(API, self).__init__(mapper)
|
||||
class QuantumApiService(WsgiService):
|
||||
"""Class for quantum-api service."""
|
||||
|
||||
@classmethod
|
||||
def create(cls, conf=None, options=None, args=None):
|
||||
app_name = "quantum"
|
||||
if not conf:
|
||||
conf_file, conf = config.load_paste_config(
|
||||
app_name, options, args)
|
||||
if not conf:
|
||||
message = (_('No paste configuration found for: %s'),
|
||||
app_name)
|
||||
raise exception.Error(message)
|
||||
print "OPTIONS:%s" %options
|
||||
print "CONF:%s" %conf
|
||||
|
||||
# Setup logging early, supplying both the CLI options and the
|
||||
# configuration mapping from the config file
|
||||
# We only update the conf dict for the verbose and debug
|
||||
# flags. Everything else must be set up in the conf file...
|
||||
# Log the options used when starting if we're in debug mode...
|
||||
|
||||
config.setup_logging(options, conf)
|
||||
debug = options.get('debug') or \
|
||||
config.get_option(conf, 'debug',
|
||||
type='bool', default=False)
|
||||
verbose = options.get('verbose') or \
|
||||
config.get_option(conf, 'verbose',
|
||||
type='bool', default=False)
|
||||
conf['debug'] = debug
|
||||
conf['verbose'] = verbose
|
||||
LOG.debug("*" * 80)
|
||||
LOG.debug("Configuration options gathered from config file:")
|
||||
LOG.debug(conf_file)
|
||||
LOG.debug("================================================")
|
||||
items = dict([(k, v) for k, v in conf.items()
|
||||
if k not in ('__file__', 'here')])
|
||||
for key, value in sorted(items.items()):
|
||||
LOG.debug("%(key)-30s %(value)s" % locals())
|
||||
LOG.debug("*" * 80)
|
||||
service = cls(app_name, conf_file, conf)
|
||||
return service
|
||||
|
||||
|
||||
def app_factory(global_conf, **local_conf):
|
||||
conf = global_conf.copy()
|
||||
conf.update(local_conf)
|
||||
return API(conf)
|
||||
def serve_wsgi(cls, conf=None, options = None, args = None):
|
||||
try:
|
||||
service = cls.create(conf, options, args)
|
||||
except Exception:
|
||||
logging.exception('in WsgiService.create()')
|
||||
raise
|
||||
|
||||
service.start()
|
||||
|
||||
return service
|
||||
|
||||
|
||||
def _run_wsgi(app_name, paste_conf, paste_config_file):
|
||||
print "CICCIO"
|
||||
LOG.info(_('Using paste.deploy config at: %s'), paste_config_file)
|
||||
app = config.load_paste_app(paste_config_file, app_name)
|
||||
if not app:
|
||||
LOG.error(_('No known API applications configured in %s.'),
|
||||
paste_config_file)
|
||||
return
|
||||
server = wsgi.Server()
|
||||
server.start(app,
|
||||
int(paste_conf['bind_port']),paste_conf['bind_host'])
|
||||
return server
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user