Enhance wsgi to listen on ipv6 address
Check if the hostname is ipv6 and set the family appropriately. Picked up the code snippet from glance to determine the address_family per markmclain's comment Picked up some code from nova as well to get the test case running properly Fixes LP# 1101341 Change-Id: I67166dc030e4ea0dd82888abfbc9db555747de27
This commit is contained in:
parent
61a4bd7124
commit
20314e0ba0
|
@ -0,0 +1,69 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 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.
|
||||
|
||||
import mock
|
||||
import socket
|
||||
|
||||
import unittest2 as unittest
|
||||
|
||||
from quantum import wsgi
|
||||
|
||||
|
||||
class TestWSGIServer(unittest.TestCase):
|
||||
"""WSGI server tests."""
|
||||
|
||||
def test_start_random_port(self):
|
||||
server = wsgi.Server("test_random_port")
|
||||
server.start(None, 0, host="127.0.0.1")
|
||||
self.assertNotEqual(0, server.port)
|
||||
server.stop()
|
||||
server.wait()
|
||||
|
||||
def test_start_random_port_with_ipv6(self):
|
||||
server = wsgi.Server("test_random_port")
|
||||
server.start(None, 0, host="::1")
|
||||
self.assertEqual("::1", server.host)
|
||||
self.assertNotEqual(0, server.port)
|
||||
server.stop()
|
||||
server.wait()
|
||||
|
||||
|
||||
class TestWSGIServer2(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.eventlet_p = mock.patch.object(wsgi, 'eventlet')
|
||||
self.eventlet = self.eventlet_p.start()
|
||||
self.server = wsgi.Server("test_app")
|
||||
|
||||
def tearDown(self):
|
||||
self.eventlet_p.stop()
|
||||
|
||||
def test_ipv6_with_link_local_start(self):
|
||||
mock_app = mock.Mock()
|
||||
with mock.patch.object(self.server, 'pool') as pool:
|
||||
self.server.start(mock_app,
|
||||
0,
|
||||
host="fe80::204:acff:fe96:da87%eth0")
|
||||
self.eventlet.assert_has_calls([
|
||||
mock.call.listen(('fe80::204:acff:fe96:da87%eth0', 0, 0, 2),
|
||||
backlog=128,
|
||||
family=10)
|
||||
])
|
||||
pool.spawn.assert_has_calls([mock.call(
|
||||
self.server._run,
|
||||
mock_app,
|
||||
self.eventlet.listen.mock_calls[0].return_value)
|
||||
])
|
|
@ -18,6 +18,7 @@
|
|||
"""
|
||||
Utility methods for working with WSGI servers
|
||||
"""
|
||||
import socket
|
||||
import sys
|
||||
from xml.dom import minidom
|
||||
from xml.parsers import expat
|
||||
|
@ -51,8 +52,40 @@ class Server(object):
|
|||
|
||||
def start(self, application, port, host='0.0.0.0', backlog=128):
|
||||
"""Run a WSGI server with the given application."""
|
||||
socket = eventlet.listen((host, port), backlog=backlog)
|
||||
self.pool.spawn_n(self._run, application, socket)
|
||||
self._host = host
|
||||
self._port = port
|
||||
|
||||
# TODO(dims): eventlet's green dns/socket module does not actually
|
||||
# support IPv6 in getaddrinfo(). We need to get around this in the
|
||||
# future or monitor upstream for a fix
|
||||
try:
|
||||
info = socket.getaddrinfo(self._host,
|
||||
self._port,
|
||||
socket.AF_UNSPEC,
|
||||
socket.SOCK_STREAM)[0]
|
||||
family = info[0]
|
||||
bind_addr = info[-1]
|
||||
|
||||
self._socket = eventlet.listen(bind_addr,
|
||||
family=family,
|
||||
backlog=backlog)
|
||||
except:
|
||||
LOG.exception(_("Unable to listen on %(host)s:%(port)s") %
|
||||
{'host': host, 'port': port})
|
||||
sys.exit(1)
|
||||
|
||||
self._server = self.pool.spawn(self._run, application, self._socket)
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
return self._socket.getsockname()[0] if self._socket else self._host
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return self._socket.getsockname()[1] if self._socket else self._port
|
||||
|
||||
def stop(self):
|
||||
self._server.kill()
|
||||
|
||||
def wait(self):
|
||||
"""Wait until all servers have completed running."""
|
||||
|
|
Loading…
Reference in New Issue