Make sure use IPv6 sockets for ceilometer in IPv6 environment

In IPv6 management network environment, ceilometer command will
throw 'Address family for hostname not support' when use WSGI
simple server. The root cause is python TCPServer implementation
is hard-coded to use IPv4, even in IPv6 environments. Python
community want to fix it in Python3.5, so we need to make a
workaround for it.

Change-Id: I3260a346a095b0f3e57093c18b1920dffe5ac55d
Closes-Bug: #1269243
This commit is contained in:
Dazhao 2014-01-20 15:32:45 +08:00 committed by Yang Yu
parent 9a489b5d41
commit c843acb4f6
3 changed files with 63 additions and 1 deletions

View File

@ -18,8 +18,10 @@
import logging
import os
import socket
from wsgiref import simple_server
import netaddr
from oslo.config import cfg
import pecan
@ -106,6 +108,20 @@ class VersionSelectorApplication(object):
return self.v2(environ, start_response)
def get_server_cls(host):
"""Return an appropriate WSGI server class base on provided host
:param host: The listen host for the ceilometer API server.
"""
server_cls = simple_server.WSGIServer
if netaddr.valid_ipv6(host):
# NOTE(dzyu) make sure use IPv6 sockets if host is in IPv6 pattern
if getattr(server_cls, 'address_family') == socket.AF_INET:
class server_cls(server_cls):
address_family = socket.AF_INET6
return server_cls
def start():
service.prepare_service()
@ -114,7 +130,8 @@ def start():
# Create the WSGI server and start it
host, port = cfg.CONF.api.host, cfg.CONF.api.port
srv = simple_server.make_server(host, port, root)
server_cls = get_server_cls(host)
srv = simple_server.make_server(host, port, root, server_cls)
LOG.info(_('Starting server in PID %s') % os.getpid())
LOG.info(_("Configuration:"))

View File

@ -0,0 +1,44 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2014 IBM Corp.
# 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 socket
from oslo.config import cfg
from ceilometer.api import app
from ceilometer.openstack.common.fixture import config
from ceilometer.tests import base
class TestApp(base.BaseTestCase):
def setUp(self):
super(TestApp, self).setUp()
self.CONF = self.useFixture(config.Config()).conf
def test_WSGI_address_family(self):
self.CONF.set_override('host', '::', group='api')
server_cls = app.get_server_cls(cfg.CONF.api.host)
self.assertEqual(server_cls.address_family, socket.AF_INET6)
self.CONF.set_override('host', '127.0.0.1', group='api')
server_cls = app.get_server_cls(cfg.CONF.api.host)
self.assertEqual(server_cls.address_family, socket.AF_INET)
self.CONF.set_override('host', 'ddddd', group='api')
server_cls = app.get_server_cls(cfg.CONF.api.host)
self.assertEqual(server_cls.address_family, socket.AF_INET)

View File

@ -12,6 +12,7 @@ kombu>=2.4.8
lockfile>=0.8
lxml>=2.3
msgpack-python
netaddr>=0.7.6
oslo.config>=1.2.0
oslo.vmware
pbr>=0.6,<1.0