From b8fca650b41e894d057a10970c6eec412716ff57 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 10 Jan 2013 11:26:03 -0500 Subject: [PATCH] Enhance wsgi to listen on ipv6 address Check if the hostname is ipv6 and set the family appropriately. Picking up the snippet from glance. Picked up some code from nova as well to get the test case running properly Change-Id: Ic79fcda2371f0907d75a142ea18b26b3e8d92e51 --- cinder/tests/test_wsgi.py | 10 ++++++++++ cinder/wsgi.py | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cinder/tests/test_wsgi.py b/cinder/tests/test_wsgi.py index 08b933809..c0eb434e2 100644 --- a/cinder/tests/test_wsgi.py +++ b/cinder/tests/test_wsgi.py @@ -93,6 +93,16 @@ class TestWSGIServer(unittest.TestCase): server.stop() server.wait() + def test_start_random_port_with_ipv6(self): + server = cinder.wsgi.Server("test_random_port", + None, + host="::1") + server.start() + self.assertEqual("::1", server.host) + self.assertNotEqual(0, server.port) + server.stop() + server.wait() + class ExceptionTest(test.TestCase): diff --git a/cinder/wsgi.py b/cinder/wsgi.py index 4a3aa1cba..979b8eae8 100644 --- a/cinder/wsgi.py +++ b/cinder/wsgi.py @@ -19,6 +19,7 @@ """Utility methods for working with WSGI servers.""" +import socket import sys import eventlet @@ -58,8 +59,8 @@ class Server(object): """ self.name = name self.app = app - self.host = host or "0.0.0.0" - self.port = port or 0 + self._host = host or "0.0.0.0" + self._port = port or 0 self._server = None self._socket = None self._protocol = protocol @@ -90,10 +91,35 @@ class Server(object): if backlog < 1: raise exception.InvalidInput( reason='The backlog must be more than 1') - self._socket = eventlet.listen((self.host, self.port), backlog=backlog) + + bind_addr = (self._host, self._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(bind_addr[0], + bind_addr[1], + socket.AF_UNSPEC, + socket.SOCK_STREAM)[0] + family = info[0] + bind_addr = info[-1] + except Exception: + family = socket.AF_INET + + self._socket = eventlet.listen(bind_addr, + family, + backlog=backlog) self._server = eventlet.spawn(self._start) - (self.host, self.port) = self._socket.getsockname() - LOG.info(_("Started %(name)s on %(host)s:%(port)s") % self.__dict__) + (self._host, self._port) = self._socket.getsockname()[0:2] + LOG.info(_("Started %(name)s on %(_host)s:%(_port)s") % self.__dict__) + + @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): """Stop this server. -- 2.45.2